本文主要是介绍Contest - ACdream原创群赛の妹子的假期生活 解题报告,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
总体情况:
昨天做的人不是很多啊T_T , 以下是Board
感谢帮我验题的同学们:
本来想是覆盖所有知识点的,失败T_T ,木有出字符串,搜索也是图论过的T_T
P.S.
本次解题报告代码要和http://blog.csdn.net/dslovemz/article/details/8435024 配套使用
A 孟竹的Triple
Dynamic Programming
仿照本次长春赛区H题出的一个题目。
状态是 dp[数个数][和][LCM][异或值]。不过这样肯定是要MLE+TLE的。于是两种优化:
1、数的个数,因为递推的时候只会从 i -> i + 1于是用滚动数组
2、LCM , 预处理1~100所有数字的约数,以及两个约数LCM
typedef long long int64;struct Int {int x;Int() :x(0) {}Int(int _x) :x(_x) {x %= MOD;if (x < 0)x += MOD;}Int(int64 _x) {x = _x % MOD;if (x < 0)x += MOD;}static Int get(int x) {Int a;a.x = x;return a;}Int operator+(const Int&o) const {int t = x + o.x;if (t >= MOD)t -= MOD;return get(t);}Int operator*(const Int&o) const {return get(1LL * x * o.x % MOD);}Int operator-(const Int&o) const {int t = x - o.x;if (t < 0)t += MOD;return get(t);}Int operator/(const Int&o) const {return (*this) * o.inv();}Int&operator+=(const Int&o) {return (*this) = *this + o;}Int&operator-=(const Int&o) {return (*this) = *this - o;}Int&operator*=(const Int&o) {return (*this) = *this * o;}Int&operator/=(const Int&o) {return (*this) = *this / o;}Int power(int64 n) const {if (!n)return get(1);const Int&a = *this;if (n & 1)return power(n - 1) * a;elsereturn (a * a).power(n >> 1);}Int inv() const {return power(MOD - 2);}
};
/* .................................................................................................................................. */
Int dp[2][102][15][139];
VI Factor[101];
int FactorP[101][101] , lcmP[101][101][101] , FactorCnt[101];
int n , a , b , c;
void init(){for (int i = 0 ; i <= 100 ; ++i)Factor[i].clear();RST(FactorP);RST(lcmP);for (int i = 1 ; i <= 100 ; ++i){for (int j = 1 ; j <= i ; ++j)if (i % j == 0){Factor[i].PB(j);FactorP[i][j] = SZ(Factor[i]) - 1;}FactorCnt[i] = SZ(Factor[i]);}for (int i = 1 ; i <= 100 ; ++i){for (int j = 0 ; j < FactorCnt[i] ; ++j)for (int k = 0 ; k < FactorCnt[i] ; ++k){int p = Factor[i][j];int q = Factor[i][k];int r = p / GCD(p , q) * q;r = FactorP[i][r];lcmP[i][j][k] = r;}}
}
void solve(){RD(n , a , b , c);RST(dp);dp[0][0][0][0].x = 1;for (int i = 0 ; i < n ; ++i){int nw = i & 1;int nx = 1 - nw;for (int sum = 0 ; sum <= a ; ++sum)for (int lcmnow = 0 ; lcmnow < FactorCnt[b] ; ++lcmnow)for (int xorsum = 0 ; xorsum <= 128 ; ++xorsum)dp[nx][sum][lcmnow][xorsum].x = 0;for (int sum = 0 ; sum <= a ; ++sum)for (int lcmnow = 0 ; lcmnow < FactorCnt[b] ; ++lcmnow)for (int xorsum = 0 ; xorsum < 128 ; ++xorsum){
// printf("dp[%d][%d][%d][%d] = %d\n" , nw , sum , lcmnow , xorsum , dp[nw][sum][lcmnow][xorsum]);if (dp[nw][sum][lcmnow][xorsum].x == 0) continue;for (int add = 0 ; add < FactorCnt[b] && Factor[b][add] + sum <= a; ++add){int addFactor = Factor[b][add];
// printf("ADD dp[%d][%d][%d][%d] += %d\n" , nx , sum + addFactor , lcmP[b][lcmnow][add] , (xorsum ^ addFactor) , dp[nw][sum][lcmnow][xorsum].x);dp[nx][sum + addFactor][lcmP[b][lcmnow][add]][(xorsum ^ addFactor)] += dp[nw][sum][lcmnow][xorsum];}}}printf("%d\n" , dp[(n & 1)][a][FactorP[b][b]][c].x);
// if (dp[(n & 1)][a][FactorP[b][b]][c].x) printf("%d %d %d %d\n" , n , a , b , c);
}
int main(){freopen("0.in" , "r" , stdin);freopen("0.out" , "w" , stdout);init();Rush solve();
}
B 孟竹的复习计划
动态求逆序对,树状数组 / 线段树。
这题其实是有一次我做CF的时候看错题了,突然想到的T_T
方法是开100棵树状数组,每次询问花100 * logn的时间,所以复杂度就是(n + m)*100 * logn
SEGMENT - TREE
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 10009;
struct TREE{int tree[maxn<<2];void PushUP(int rt) {tree[rt] = (tree[rt<<1] + tree[rt<<1|1]);}void build(int l,int r,int rt) {if (l == r) {//scanf("%d",&tree[rt]);tree[rt] = 0;return ;}int m = (l + r) >> 1;build(lson);build(rson);PushUP(rt);}void update(int p,int sc,int l,int r,int rt) {if (l == r) {tree[rt] = sc;return ;}int m = (l + r) >> 1;if (p <= m) update(p , sc , lson);else update(p , sc , rson);PushUP(rt);}int query(int L,int R,int l,int r,int rt) {if (L <= l && r <= R) {return tree[rt];}int m = (l + r) >> 1;int ret = 0;if (L <= m) {int res= query(L , R , lson);ret += (res);}if (R > m) {int res= query(L , R , rson);ret += (res);}return ret;}
}tree[109];
int a[maxn] , n , m;
struct IO{int op , x , y;void input(){RD(op , x , y);}
}io[10009];
VI hashT;
VI edge[109];
MII hash;
int L;
int cal(int po , int val){int res = 0;for (int i = 1 ; i <= L ; ++i){if (i < val && po < n)res += tree[i].query(po + 1 , n , 1 , n , 1);if (i > val && po > 1)res += tree[i].query(1 , po - 1 , 1 , n , 1);}return res;
}
void changeNumber(int po , int val){tree[a[po]].update(po , 0 , 1 , n , 1);tree[val].update(po , 1 , 1 , n , 1);
}
void solve(){RD(n , m);hash.clear();hashT.clear();for (int i = 1 ; i <= n ; ++i) RD(a[i]) , hashT.PB(a[i]);for (int i = 1 ; i <= m ; ++i){io[i].input();if (io[i].op == 0) hashT.PB(io[i].y);}sort(ALL(hashT));L = unique(ALL(hashT)) - hashT.begin();for (int i = 0 ; i < L ; ++i)hash[hashT[i]] = i + 1 ;for (int i = 1 ; i <= n ; ++i) a[i] = hash[a[i]];for (int i = 1 ; i <= m ; ++i)if (io[i].op == 0)io[i].y = hash[io[i].y];for (int i = 0 ; i <= L ; ++i){tree[i].build(1 , n , 1);edge[i].clear();}for (int i = 1 ; i <= n ; ++i){edge[a[i]].PB(i);}int ans = 0;for (int i = 1 ; i <= L ; ++i){for (int j = 0 ; j < SZ(edge[i]) ; ++j){int now = edge[i][j];if (now < n) ans += tree[0].query(now + 1 , n , 1 , n , 1);}for (int j = 0 ; j < SZ(edge[i]) ; ++j){int now = edge[i][j];tree[0].update(now , 1 , 1 , n , 1);}}tree[0].build(1 , n , 1);for (int i = 1 ; i <= n ; ++i)tree[a[i]].update(i , 1 , 1 , n , 1);printf("%d\n" , ans);for (int cas = 1 ; cas <= m ; ++cas){int op = io[cas].op , x = io[cas].x , y = io[cas].y;int change = 0;if (op == 0){change -= cal(x , a[x]);change += cal(x , y);ans += change;changeNumber(x , y);a[x] = y;}else{if (x > y) swap(x , y);change -= cal(x , a[x]);change -= cal(y , a[y]);changeNumber(x , a[y]);changeNumber(y , a[x]);swap(a[x] , a[y]);change += cal(x , a[x]);change += cal(y , a[y]);if (a[x] > a[y]) change--;else if (a[x] < a[y]) change++;ans += change;}printf("%d\n" , ans);}
}
int main(){
// freopen("0.in" , "r" , stdin);
// freopen("segmengtree.out" , "w" , stdout);Rush solve();
}
BIT
const int maxn = 10009;
int n;
struct TREE{int tree[maxn] , cnt;void init(){RST(tree);cnt = 0;}void add(int po , int c){for ( ; po< maxn ; po += low_bit(po))tree[po] += c;cnt += c;}int query(int po){int ret = 0;for (; po > 0 ; po -= low_bit(po))ret += tree[po];return ret;}
}tree[109];
int a[maxn] , m;
struct IO{int op , x , y;void input(){RD(op , x , y);}
}io[10009];
VI hashT;
VI edge[109];
MII hash;
int L;
int cal(int po , int val){int res = 0;for (int i = 1 ; i <= L ; ++i){if (i < val && po < n)res += tree[i].cnt - tree[i].query(po - 1);if (i > val && po > 1)res += tree[i].query(po - 1);}return res;
}
void changeNumber(int po , int val){tree[a[po]].add(po , -1);tree[val].add(po , 1);
}
void solve(){RD(n , m);hash.clear();hashT.clear();for (int i = 1 ; i <= n ; ++i) RD(a[i]) , hashT.PB(a[i]);for (int i = 1 ; i <= m ; ++i){io[i].input();if (io[i].op == 0) hashT.PB(io[i].y);}sort(ALL(hashT));L = unique(ALL(hashT)) - hashT.begin();for (int i = 0 ; i < L ; ++i)hash[hashT[i]] = i + 1 ;for (int i = 1 ; i <= n ; ++i) a[i] = hash[a[i]];for (int i = 1 ; i <= m ; ++i)if (io[i].op == 0)io[i].y = hash[io[i].y];for (int i = 0 ; i <= L ; ++i){tree[i].init();edge[i].clear();}for (int i = 1 ; i <= n ; ++i){edge[a[i]].PB(i);}int ans = 0;for (int i = L ; i >= 1 ; --i){for (int j = 0 ; j < SZ(edge[i]) ; ++j){int now = edge[i][j];ans += tree[0].query(now);}for (int j = 0 ; j < SZ(edge[i]) ; ++j){int now = edge[i][j];tree[0].add(now , 1);}}tree[0].init();for (int i = 1 ; i <= n ; ++i)tree[a[i]].add(i , 1);printf("%d\n" , ans);for (int cas = 1 ; cas <= m ; ++cas){int op = io[cas].op , x = io[cas].x , y = io[cas].y;int change = 0;if (op == 0){change -= cal(x , a[x]);changeNumber(x , y);change += cal(x , y);ans += change;a[x] = y;}else{if (x > y) swap(x , y);change -= cal(x , a[x]);change -= cal(y , a[y]);changeNumber(x , a[y]);changeNumber(y , a[x]);swap(a[x] , a[y]);change += cal(x , a[x]);change += cal(y , a[y]);if (a[x] > a[y]) change--;else if (a[x] < a[y]) change++;ans += change;}printf("%d\n" , ans);}
}
int main(){
// freopen("0.in" , "r" , stdin);
// freopen("bit.out" , "w" , stdout);Rush solve();
}
XLK 的 二维BIT
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<vector>
using namespace std;
#define fr(i,n) for(int i=0;i<n;i++)
#define fo(i,n) for(int i=1;i<=n;i++)
#define fe(i,n) for(__typeof(n.begin()) i=n.begin();i!=n.end();i++)
int c[105][10020];
int a[10020];
int n,m,z,t;
int R(int x,int y,int z)
{for(int i=x;i<=100;i+=i&-i)for(int j=y;j<=n;j+=j&-j)c[i][j]+=z;
}
int G(int x,int y)
{int _=0;for(int i=x;i;i-=i&-i)for(int j=y;j;j-=j&-j)_+=c[i][j];return _;
}
void C(int p,int x)
{R(a[p],p,-1);z-=G(100,p)-G(a[p],p);z-=G(a[p]-1,n)-G(a[p]-1,p);a[p]=x;R(a[p],p,+1);z+=G(100,p)-G(a[p],p);z+=G(a[p]-1,n)-G(a[p]-1,p);
}
int main()
{for(scanf("%d",&t);t--;){z=0;memset(c,0,sizeof c);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",a+i);z+=G(100,i)-G(a[i],i);R(a[i],i,1);}printf("%d\n",z);for(int i=0;i<m;i++){int o,x,y;scanf("%d%d%d",&o,&x,&y);if(o==1){int ax=a[x],ay=a[y];C(x,ay);C(y,ax);}else{C(x,y);}printf("%d\n",z);}}
}
C 孟竹的幼儿园生活
简单计算几何。
分成两部分:
1、给正方形对角线,求四个角——模板
2、HPI , nlogn半平面交
XLK 的代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
const double inf=1e8;
const double eps=1e-8;
const double pi=acos(-1.);
using namespace std;
struct P
{double x,y;P(){}P(double x,double y):x(x),y(y){}void scan(){scanf("%lf %lf",&x,&y);}void print(string s=""){if(s!="")cout << s << ": ";printf("%.2f %.2f\n",x,y);}double dis(const P&a){return hypot(x-a.x,y-a.y);}P rot(double f){double sf=sin(f),cf=cos(f);return P(x*cf-y*sf,y*cf+x*sf);}double dot(const P&a){return x*a.x+y*a.y;}double det(const P&a){return x*a.y-y*a.x;}
}p[4020],s[4020],o;bool operator==(const P&a,const P&b){return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps;}bool operator!=(const P&a,const P&b){return !(a==b);}bool operator<(const P&a,const P&b){if(fabs(a.x-b.x)<eps)return a.y<b.y;return a.x<b.x;}P operator+(const P&a,const P&b){return P(a.x+b.x,a.y+b.y);}P operator-(const P&a,const P&b){return P(a.x-b.x,a.y-b.y);}P operator/(const P&a,double f){return P(a.x/f,a.y/f);}P operator*(const P&a,double f){return P(a.x*f,a.y*f);}
int pc,sc;
double r;
int sgn(double x)
{return (x>eps)-(x<-eps);
}
double xm(P a,P b,P c)
{return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
P cp(P as,P ae,P bs,P be)
{P re;double u=xm(as,ae,bs);double v=xm(ae,as,be);re.x=(bs.x*v+be.x*u)/(u+v);re.y=(bs.y*v+be.y*u)/(u+v);return re;
}
void ins(P a,P b)
{int i;sc=0;for(i=1;i<pc;i++){if(sgn(xm(a,b,p[i]))>=0)s[++sc]=p[i];if(sgn(xm(a,b,p[i])*xm(a,b,p[i+1]))<0)s[++sc]=cp(a,b,p[i],p[i+1]);}pc=sc;if(sc==0)return;memcpy(p,s,sizeof(p));p[++pc]=p[1];return;
}
void mov(P a,P b,P&c,P&d)
{P o=P(a.y-b.y,b.x-a.x);double l=sqrt(o.x*o.x+o.y*o.y);o.x=o.x/l*r;o.y=o.y/l*r;c.x=a.x+o.x;c.y=a.y+o.y;d.x=b.x+o.x;d.y=b.y+o.y;return;
}
double dis(P a,P b)
{return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
double S(P p[],int n)
{double re=0;int i;for(i=1;i<n;i++)re+=xm(o,p[i],p[i+1]);return fabs(re/2);
}
int main()
{int t;for(scanf("%d",&t);t--;){int n,i,j,ans1,ans2;double ans=0,ds;scanf("%d",&n);p[1]=P(-10000,-10000);p[2]=P(10000,-10000);p[3]=P(10000,10000);p[4]=P(-10000,10000);p[pc=5]=p[1];for(i=1;i<=n;i++){P u,v,o,p,q;u.scan();v.scan();o=(u+v)/2;p=(u-o).rot(pi/2)+o;q=(v-o).rot(pi/2)+o;ins(u,p);ins(p,v);ins(v,q);ins(q,u);}printf("%.4f\n",S(p,pc));}return 0;
}
D 孟竹跪DP
也是一个CF的原题。方法是枚举每个数字,记录左边离这个数字最近的二进制第i位是0或者1的数字的位置,暴力优化。复杂度O(n)
bool ans[2000000];
int MI[31];
void init(){for (int i = 0 ; i <= 29 ; ++i)MI[i] = 1 << i;
}
int n;
struct Meng{int t , po;bool operator < (const Meng & A) const{if (po != A.po) return po > A.po;return t < A.t;}
}dp0[31] , dp1[31];
const int ALL = (1 << 21) - 1;
bool cmp(Meng A , Meng B){return A.t < B.t;
}
#define LIMIT 21
int po0[LIMIT + 1] , po1[LIMIT + 1];
void solve(){RD(n);RST(ans);
//cout << ALL << endl;for (int i = 0 ; i < LIMIT ; ++i){dp0[i].t = i , dp1[i].t = i;dp0[i].po = -1 , dp1[i].po = -1;}for (int i = 0 ; i < n ; ++i){int x , y , z;RD(x);y = x , z = x;ans[x] = 1;for (int j = 0 ; j < LIMIT ; ++j){po0[dp0[j].t] = j;po1[dp1[j].t] = j;}for (int j = 0 ; j < LIMIT ; ++j){if(x & 1) dp1[po1[j]].po = i;else dp0[po0[j]].po = i;x >>= 1;}sort(dp0 , dp0 + LIMIT);sort(dp1 , dp1 + LIMIT);
//cout << i << endl;for(int j = 0 ; j < LIMIT ; ++j){if (dp0[j].po != -1){
//cout << "0"<<j<<endl;
//cout << dp0[j].t<<endl;y &= (ALL ^ MI[dp0[j].t]);if (j == LIMIT - 1 || dp0[j].po != dp0[j + 1].po){
//cout << y << endl;ans[y] = 1;}}if (dp1[j].po != -1){
//cout << "1"<<j<<endl;z |= MI[dp1[j].t];if (j == LIMIT - 1 || dp1[j].po != dp1[j + 1].po){
//cout << z << endl;ans[z] = 1;}}}}
//cout << "DS" << endl;int ANS = 0;for (int i = 0 ; i < 2000000 ; ++i)if (ans[i]) {
//cout << i << endl;++ANS;}printf("%d\n" , ANS);
}
int main(){freopen("0.in" , "r" , stdin);freopen("0.out" , "w" , stdout);init();Rush solve();
}
bool ans[2000000];
int MI[31];
void init(){for (int i = 0 ; i <= 29 ; ++i)MI[i] = 1 << i;
}
int n;
struct Meng{int t , po;bool operator < (const Meng & A) const{if (po != A.po) return po > A.po;return t < A.t;}
}dp0[31] , dp1[31];
const int ALL = (1 << 21) - 1;
bool cmp(Meng A , Meng B){return A.t < B.t;
}
#define LIMIT 21
int po0[LIMIT + 1] , po1[LIMIT + 1];
void solve(){RD(n);RST(ans);
//cout << ALL << endl;for (int i = 0 ; i < LIMIT ; ++i){dp0[i].t = i , dp1[i].t = i;dp0[i].po = -1 , dp1[i].po = -1;}for (int i = 0 ; i < n ; ++i){int x , y , z;RD(x);y = x , z = x;ans[x] = 1;for (int j = 0 ; j < LIMIT ; ++j){po0[dp0[j].t] = j;po1[dp1[j].t] = j;}for (int j = 0 ; j < LIMIT ; ++j){if(x & 1) dp1[po1[j]].po = i;else dp0[po0[j]].po = i;x >>= 1;}sort(dp0 , dp0 + LIMIT);sort(dp1 , dp1 + LIMIT);
//cout << i << endl;for(int j = 0 ; j < LIMIT ; ++j){if (dp0[j].po != -1){
//cout << "0"<<j<<endl;
//cout << dp0[j].t<<endl;y &= (ALL ^ MI[dp0[j].t]);if (j == LIMIT - 1 || dp0[j].po != dp0[j + 1].po){
//cout << y << endl;ans[y] = 1;}}if (dp1[j].po != -1){
//cout << "1"<<j<<endl;z |= MI[dp1[j].t];if (j == LIMIT - 1 || dp1[j].po != dp1[j + 1].po){
//cout << z << endl;ans[z] = 1;}}}}
//cout << "DS" << endl;int ANS = 0;for (int i = 0 ; i < 2000000 ; ++i)if (ans[i]) {
//cout << i << endl;++ANS;}printf("%d\n" , ANS);
}
int main(){freopen("0.in" , "r" , stdin);freopen("0.out" , "w" , stdout);init();Rush solve();
}
E 孟竹和屌丝玩儿游戏
双指针+数据结构
首先,如果要求和不大于K的话,双指针就可以解决问题。
其次如果孟竹有必胜条件的话,那么异或值肯定不能为0。反过来算,求有多少个异或为0然后用C[n][2]剪掉即可。
怎么算呢?很简单,计算所有的前缀异或值。比如当前的前缀异或为A,之前到第j个位置异或也为A,A^A = 0 ,于是j+1 -> 当前位置这段区间的异或就为0
对于0的情况要特殊讨论,因为如果前缀和 <=k 的话异或为0是要加一的否则不加
int n ;
const int N = 1e5 + 9;
LL a[N];
map<LL , LL> hash;
LL k , sum , ans;
void solve(){RD(n);RD(k);for (int i = 0 ; i < n ; ++i)RD(a[i]);hash.clear();hash[0] = 0;int tail = 0;ans = 0;sum = 0;LL xorsum = 0 , xortail = 0;LL ALL = 0;for (int i = 0 ; i < n ; ++i){sum += a[i];xorsum ^= a[i];if (hash.find(xorsum) == hash.end()) hash[ xorsum ] = 1;else hash[ xorsum ] = hash[ xorsum ] + 1;while (sum > k) {sum -= a[tail];// if(hash.find(xortail) == hash.end()) printf("%d %d\n" , i , tail);assert(hash.find(xortail) != hash.end());xortail ^= a[tail];hash[xortail] = hash[xortail ] - 1;++tail;}ALL += i - tail + 1;
// if (hash.find(xorsum) != hash.end())assert(hash.find(xorsum) != hash.end());if (tail == 0) ++ hash[0];else ++hash[(xortail)];if (tail <= i)ans += hash[ xorsum ] - 1ll;if (tail == 0) -- hash[0];else --hash[(xortail)];
// cout <<"ANS:" << ans << endl;}
// cout << ALL <<endl;ans = ALL - ans;OT(ans);
}
int main(){
// freopen("0.in" , "r" , stdin);
// freopen("0.out" , "w" , stdout);Rush solve();
}
F 孟竹要减肥?
并查集
将所有边长计算出来,从小到大加边,用并查集统计连通性,如果有一个 >= m 的连通块就结束
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include<math.h>
using namespace std;
const int N = 600;
namespace ufset{int fa[N] , rank[N] , SZ[N];void init(){for (int i = 0 ; i < N ; ++i) SZ[i] = 1 , fa[i] = i , rank[i] = 0;}int findset(int x){int r = x , y ;while(fa[r] != r) r = fa[r];while(fa[x] != r) {y = fa[x] , fa[x] = r , x = y;}return r;}void __unionset(int x , int y){if (rank[x] > rank[y]) {fa[y] = x;SZ[x] += SZ[y];}else {fa[x] = y;SZ[y] += SZ[x];if (rank[x] == rank[y]) ++ rank[y];}}void unionset(int x , int y){int rx = findset(x) , ry = findset(y);if (rx != ry) __unionset(rx , ry);}
}using namespace ufset;
struct Point{double x , y;void input(){scanf("%lf%lf" , &x , &y);}#define sqr(x) ((x) * (x))double dis(const Point & A) const{return sqrt(sqr(x - A.x) + sqr(y - A.y));}
}p[509];
int n , m ;
const double eps = 1e-8;
int dcmp(double d){if (fabs(d) < eps) return 0;return d < 0 ? -1 : 1;
}
struct Rel{int p , q;double nk;bool operator < (const Rel & A) const{return dcmp(nk - A.nk) < 0;}
}relation[509 * 509];
void solve(){scanf("%d%d" , &n,&m);for (int i = 0 ; i < n ; ++i) p[i].input();int rcnt = 0;for (int i = 0 ; i < n ; ++i)for (int j = i + 1 ; j < n ; ++j){relation[rcnt].p = i;relation[rcnt].q = j;relation[rcnt].nk = p[i].dis(p[j]);rcnt++;}sort(relation , relation + rcnt);init();for (int i = 0 ; i < rcnt ; ++i){unionset(relation[i].p , relation[i].q);int rx = findset(relation[i].p) , ry = findset(relation[i].q);if (SZ[rx] >= m || SZ[ry] >= m){printf("%.4lf\n" , relation[i].nk);return;}}
}
int main(){freopen("0.in" , "r" , stdin);freopen("0.out" , "w" , stdout);int T;scanf("%d" , &T);while(T--) solve();
}
G 孟竹的星星
水题。
标程的算法是计算出外心,然后随便找一个点,每次旋转72度即可。
看xlk的代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<math.h>
using namespace std;
#define fr(i,n) for(int i=0;i<n;i++)
#define fo(i,n) for(int i=1;i<=n;i++)
#define fe(i,n) for(__typeof(n.begin()) i=n.begin();i!=n.end();i++)const double eps=1e-4;const double pi=acos(-1.);struct P{double x,y;P(){}P(double x,double y):x(x),y(y){}void scan(){scanf("%lf %lf",&x,&y);}void print(string s=""){if(s!="")cout << s << ": ";printf("%.2f %.2f\n",x,y);}double dis(const P&a){return hypot(x-a.x,y-a.y);}P rot(double f){double sf=sin(f),cf=cos(f);return P(x*cf-y*sf,y*cf+x*sf);}double dot(const P&a){return x*a.x+y*a.y;}double det(const P&a){return x*a.y-y*a.x;}};bool operator==(const P&a,const P&b){return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps;}bool operator!=(const P&a,const P&b){return !(a==b);}bool operator<(const P&a,const P&b){if(fabs(a.x-b.x)<eps)return a.y<b.y;return a.x<b.x;}P operator+(const P&a,const P&b){return P(a.x+b.x,a.y+b.y);}P operator-(const P&a,const P&b){return P(a.x-b.x,a.y-b.y);}P operator/(const P&a,double f){return P(a.x/f,a.y/f);}P operator*(const P&a,double f){return P(a.x*f,a.y*f);}int sgn(double x){return x<-eps?-1:x>eps;}namespace triangle{P circumcenter(const P&a,const P&b,const P&c){double x1=a.x,y1=a.y,x2=b.x,y2=b.y,x3=c.x,y3=c.y;double s1=x1*x1+y1*y1,s2=x2*x2+y2*y2,s3=x3*x3+y3*y3;double rx=(y1*(s2-s3)+y2*(s3-s1)+y3*(s1-s2))/(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2));double ry=(x1*(s2-s3)+x2*(s3-s1)+x3*(s1-s2))/(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2));return P(-rx/2,ry/2);}P barycenter(const P&a,const P&b,const P&c){return (a+b+c)/3;}pair<P,double>excircle(const P&a,const P&b,const P&c){P p=circumcenter(a,b,c);return make_pair(p,p.dis(a));}}
int main()
{int t,ss;P a,b,c,d,e,w,r,p[5],s[3];for(scanf("%d",&t);t--;){a.scan();b.scan();c.scan();w=triangle::circumcenter(a,b,c);r=w-a;ss=0;p[0]=a;for(int i=1;i<5;i++)p[i]=(p[i-1]-w).rot(2*pi/5)+w;for(int i=0;i<5;i++)if(p[i]!=a&&p[i]!=b&&p[i]!=c)s[ss++]=p[i];sort(s,s+ss);for(int i=0;i<2;i++)s[i].print();}return 0;
}
H 孟竹开Party
其实本题本意是想藏起来DLX算法然后让大家用图论方法搞不定的。。。但是貌似图论也可以
先说标程解法——用一遍dfs(复杂度O(VE))来计算出来每个人直接 / 间接能Hold 住的人,然后就是 经典的可重复覆盖问题 。 中间如果一个人选择了,那么他的配偶就不能选择。
const int head=0;
//const int INF=10000000;
const int maxn = 610;
const int maxd = 1000000;
int N, M, K, cnt, res;
int mat[maxn][maxn], s[maxn], l[maxd], r[maxd], u[maxd], d[maxd], c[maxd], o[maxn], row[maxd];
bool use[maxn];
void makegragh(int &n, int &m)
{memset(mat, 0, sizeof(mat));
//初始化mat矩阵
}
void initial(int n, int m)
{memset(use, false, sizeof(use));res=n+1;int i, j, rowh;memset(s, 0, sizeof(s));for(i=head; i<=m; i++){r[i]=(i+1)%(m+1);l[i]=(i-1+m+1)%(m+1);u[i]=d[i]=i;}cnt=m+1;for(i=1; i<=n; i++){rowh=-1;for(j=1; j<=m; j++){//printf("%d", mat[i][j]);if(mat[i][j]){s[j]++;u[cnt]=u[j];d[u[j]]=cnt;u[j]=cnt;d[cnt]=j;row[cnt]=i;c[cnt]=j;if(rowh==-1){l[cnt]=r[cnt]=cnt;rowh=cnt;}else{l[cnt]=l[rowh];r[l[rowh]]=cnt;r[cnt]=rowh;l[rowh]=cnt;}cnt++;}}//puts("");}
}
void remove(int c)
{for(int i=d[c]; i!=c; i=d[i]){r[l[i]]=r[i];l[r[i]]=l[i];}
}
void resume(int c)
{for(int i=d[c]; i!=c; i=d[i])r[l[i]]=l[r[i]]=i;
}
int h()
{bool has[maxn];memset(has, false, sizeof(has));int ans=0;for(int i=r[head]; i!=head; i=r[i])if(!has[i]){ans++;for(int j=d[i]; j!=i; j=d[j])for(int k=r[j]; k!=j; k=r[k])has[c[k]]=true;}return ans;
}
int marrige[maxn];
bool dfs(int k)
{if(k+h()>=res)return false;//A* cutif(r[head]==head){if(k<res) res=k;return true;}int ms=INF, cur=0;for(int t=r[head]; t!=head; t=r[t])if(s[t]<ms){ms=s[t];cur=t;}for(int i=d[cur]; i!=cur; i=d[i]){int rr = row[i];if (marrige[rr] == 0 || use[marrige[rr]] == 0) use[rr] = 1;else continue;
// int rr = (row[i] - 1) / 2 + 1;
// if (!use[rr]) use[rr] = true;
// else continue;remove(i);for(int j=r[i]; j!=i; j=r[j]){remove(j);s[c[j]]--;}dfs(k+1);for(int j=l[i]; j!=i; j=l[j]){resume(j);s[c[j]]++;}use[rr] = false;resume(i);}return false;
}
int n , m;
int P , x , y;
VI edge[maxn];
void vdfs(int now , int x){mat[x][now] = 1;ECH(it , edge[now]){int go = *it;if (!mat[x][go]) vdfs(go , x);}
}
void solve(){RST(marrige);RST(mat);RD(n , m);
// printf("%d %d :" , n , m);for (int i = 1 ; i <= n + m ; ++i) edge[i].clear();for (int i = 1 ; i <= n + m ; ++i)edge[i].PB(i);RD(P);DO(P){RD(x , y);//mat[x][n + y] = 1;edge[x].PB(n + y);}RD(P);DO(P){RD(x , y);//mat[n + x][y] = 1;edge[n + x].PB(y);}RD(P);DO(P){RD(x , y);marrige[x] = y + n;marrige[y + n] = x;}for(int i = 1 ; i <= n + m ; ++i){vdfs(i , i);}
// for (int i = 1 ; i <= n + m ; ++i){
// for (int j = 1 ; j <= n + m ; ++j)
// printf("%d " , mat[i][j]);
// cout << endl;
// }initial(n + m , n + m);
// cout << "DS" << endl;dfs(0);cout << res << endl;
}
int main(){freopen("0.in" , "r" , stdin);freopen("0.out" , "w" , stdout);Rush solve();
}
XLK童鞋的解法是:计算出所有强连通块儿,如果每个入度为0的scc大小都大于1,那么一定有解。贪心就是看只有一个点的scc必须取。。然后如果他有情侣。。他情侣的scc就把他情侣去掉。。一直这样。。看看会不会出现擦掉之后他情侣的scc就没有别的点了
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
using namespace std;
#define fr(i,n) for(int i=0;i<n;i++)
#define fo(i,n) for(int i=1;i<=n;i++)
#define fe(i,n) for(__typeof(n.begin()) i=n.begin();i!=n.end();i++)
int t,n,m,p,q,w,scc,x,y,in[2020];
int low[2020],dfn[2020],cnt;
int v[2020],r[2020],s[2020],ss;
int f[2020],z;
vector<int>a[2020];
set<int>se[2020];
int dfs(int x)
{dfn[x]=low[x]=++cnt;s[ss++]=x;v[x]=1;fe(i,a[x]){if(!dfn[*i]){dfs(*i);low[x]=min(low[x],low[*i]);}else if(v[*i]){low[x]=min(low[x],dfn[*i]);}}if(dfn[x]==low[x]){scc++;do{v[s[ss-1]]=0;r[s[ss-1]]=scc;se[scc].insert(s[ss-1]);
// c[scc]++;}while(s[--ss]!=x);}return 0;
}
int main()
{for(scanf("%d",&t);t--;){scc=0;cnt=0;z=0;memset(in,0,sizeof in);memset(f,0,sizeof f);memset(low,0,sizeof low);memset(dfn,0,sizeof dfn);memset(v,0,sizeof v);memset(r,0,sizeof r);scanf("%d%d",&n,&m);for(int i=1;i<=m+n;i++)a[i].clear();for(int i=1;i<=m+n;i++)se[i].clear();scanf("%d",&p);for(int i=0;i<p;i++){scanf("%d%d",&x,&y);a[x].push_back(y+n);}scanf("%d",&q);for(int i=0;i<q;i++){scanf("%d%d",&x,&y);a[x+n].push_back(y);}scanf("%d",&w);for(int i=0;i<w;i++){scanf("%d%d",&x,&y);f[x]=y+n;f[y+n]=x;}for(int i=1;i<=m+n;i++)if(!dfn[i])dfs(i);queue<int>q;for(int i=1;i<=m+n;i++)fe(j,a[i])if(r[i]!=r[*j])in[r[*j]]++;for(int i=1;i<=m+n;i++)if(se[r[i]].size()==1&&in[r[i]]==0)q.push(i);for(int i=1;i<=scc;i++)if(in[i]==0)z++;while(q.size()){int u=q.front();q.pop();if(f[u]&&in[r[f[u]]]==0){se[r[f[u]]].erase(f[u]);if(se[r[f[u]]].size()==0){printf("%d\n",n+m+1);goto end;}else if(se[r[f[u]]].size()==1){q.push(*se[r[f[u]]].begin());}}}printf("%d\n",z);end:;}
}
I 孟竹画圈圈诅咒你
没啥好说的,标准数学题。
typedef long long int64;struct Int {int x;Int() :x(0) {}Int(int _x) :x(_x) {x %= MOD;if (x < 0)x += MOD;}Int(int64 _x) {x = _x % MOD;if (x < 0)x += MOD;}static Int get(int x) {Int a;a.x = x;return a;}Int operator+(const Int&o) const {int t = x + o.x;if (t >= MOD)t -= MOD;return get(t);}Int operator*(const Int&o) const {return get(1LL * x * o.x % MOD);}Int operator-(const Int&o) const {int t = x - o.x;if (t < 0)t += MOD;return get(t);}Int operator/(const Int&o) const {return (*this) * o.inv();}Int&operator+=(const Int&o) {return (*this) = *this + o;}Int&operator-=(const Int&o) {return (*this) = *this - o;}Int&operator*=(const Int&o) {return (*this) = *this * o;}Int&operator/=(const Int&o) {return (*this) = *this / o;}Int power(int64 n) const {if (!n)return get(1);const Int&a = *this;if (n & 1)return power(n - 1) * a;elsereturn (a * a).power(n >> 1);}Int inv() const {return power(MOD - 2);}
};/* .................................................................................................................................. */
Int D(Int n){Int ret;ret = n * (n + 1) / 2;ret = ret + 1;return ret;
}
void solve(){char op[2];Int n , ans;scanf("%s%d" , op , &n.x);if (op[0] == 'L'){ans = D(n);//cout << ans.x << endl;OT(ans.x);}else if (op[0] == 'V'){ans = D(n * 2);ans = ans - n * 2;//cout << ans.x << endl;OT(ans.x);}else if (op[0] == 'Z'){ans = D(n * 3);ans = ans - n * 5;//cout << ans.x << endl;OT(ans.x);}
}
int main(){freopen("0.in" , "r" , stdin);freopen("0.out" , "w" , stdout);Rush solve();
}
cxlove 的代码:
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<set>
#include<string>
#include<queue>
#define inf 1000000005
#define M 40
#define N 100005
#define maxn 300005
#define eps 1e-12
#define zero(a) fabs(a)<eps
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)
#define mem(a,b) memset(a,b,sizeof(a))
#define LL long long
#define MOD 1000000009
#define lson step<<1
#define rson step<<1|1
#define sqr(a) ((a)*(a))
#define Key_value ch[ch[root][1]][0]
#define test puts("OK");
#define pi acos(-1.0)
#define lowbit(x) ((-(x))&(x))
#define HASH1 1331
#define HASH2 10001
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
LL a,b,c;
int main(){//freopen("input.txt","r",stdin);int t;char str[10];cin>>t;while(t--){scanf("%s%d" , str , &a);LL ans;if(str[0]=='L') ans=(a*(a+1)/2 + 1)%MOD;else if(str[0]=='V') ans=(2*a*(2*a+1)/2+1-2*a)%MOD;else ans=(3*a*(3*a+1)/2+1-5*a)%MOD;cout<<ans<<endl;}return 0;
}
J 孟竹搭积木
这题数据有错误貌似,大家抱歉了。
方法是状态压缩DP + 矩阵乘法 + 枚举 + 记忆化搜索
先说做法吧——
1、状态压缩,把一层的占有方法用2^7的一个向量记录。
2、暴力枚举第一层的情况,将只有一层的每个状态拼接方法数计算出来——initial P
3、记忆化搜索+枚举计算出转移矩阵Q,即从i层状态转移到第i层填满并且i+1层的另一个状态的转移方案数——initial Q
4、矩阵乘法,计算 P * (E + Q + Q^2 +... + Q^(N))
我的代码(虽然有错,方法是对的T_T)
const int MATN = 129;
const LL modo = MOD;
struct Mat{int Matn , Matm;LL a[MATN][MATN];Mat(){Matn = 0;Matm = 0;memset(a , 0 , sizeof(a));}void output(){cout << "OUTPUT" << endl;for (int i = 0 ; i < Matn ; ++i){for (int j = 0 ; j < Matm ; ++j){printf("%lld ",a[i][j]);}printf("\n");}}void init(){Matn = 0;Matm = 0;memset(a , 0 , sizeof(a));}Mat operator + (const Mat & A) const{Mat ret = A;for (int i = 0 ; i < Matn ; ++i){for (int j = 0 ; j < Matm ; ++j)ret.a[i][j] = (ret.a[i][j] + a[i][j]) % modo;}return ret;}Mat operator * (const Mat & A) const{Mat c ;c.Matn = Matn;c.Matm = A.Matm;for (int i = 0 ; i < Matn ; ++i)for (int j = 0 ; j < A.Matm ; ++j)for (int k = 0 ; k < Matm ; ++k)c.a[i][j] = (c.a[i][j] + (a[i][k] * A.a[k][j])%modo)%modo;return c;}void initI(){memset(a, 0 , sizeof(a));for (int i = 0 ; i < Matn ; ++i)a[i][i] = 1;}Mat power(LL k){Mat c = *this , b;b.init();b.Matn = Matn ; b.Matm = Matm;b.initI();while(k){if (k & 1LL)b = b * c;c = c * c;k >>= 1LL;}return b;}
}QQ;
struct ZHU{Mat a[2][2];void init(const Mat& p){for (int i = 0 ; i < 2 ; ++i)for (int j= 0 ; j < 2 ;++j){a[i][j].init();a[i][j].Matn = 128 ; a[i][j].Matm = 128;}a[0][0] = p;a[0][1].initI();a[1][1].initI();}void initI(){for (int i = 0 ; i < 2 ; ++i)for (int j= 0 ; j < 2 ;++j){a[i][j].Matn = 128 ; a[i][j].Matm = 128;a[i][i].initI();}}ZHU operator * (const ZHU & A) const{ZHU res;for (int i = 0 ; i < 2 ; ++i)for (int j= 0 ; j < 2 ;++j){res.a[i][j].init();res.a[i][j].Matn = 128 ; res.a[i][j].Matm = 128;}for (int i = 0 ; i < 2 ; ++i)for (int j = 0 ; j < 2 ; ++j)for (int k = 0 ; k < 2 ; ++k)res.a[i][j] = (res.a[i][j] + a[i][k] * A.a[k][j]);return res;}void copy(const ZHU & A) {for(int i = 0 ; i < 2 ; ++i)for (int j = 0 ; j < 2 ; ++j)a[i][j] = A.a[i][j];}Mat power(LL k);
}R , nR , b , c;
Mat ZHU::power(LL k){
// printf("\nINT ");
// cout << k << endl;c = *this;bool f = false;while(k){if (k & 1LL){if (!f) b = c;else b = b * c;f = true;}c = c * c;k >>= 1LL;}if (!f){b = c;b.a[0][1].initI();}return b.a[0][1];
}
const int PCODE[] = {0 , 1 , 2 , 4 , 8 , 16 , 32 , 64 , 0};
struct Under{bool mp[3][3];int hash;int encode(){hash = 0;for (int i = 0 ; i < 3 ; ++i)for(int j = 0 ; j < 3 ; ++j)if (mp[i][j])hash |= PCODE[i * 3 + j];return hash;}void decode(){RST(mp);for (int i = 0 ; i < 3 ; ++i)for(int j = 0 ; j < 3 ; ++j){if (i + j == 0 || i + j == 4) continue;if (hash & (PCODE[i * 3 + j]))mp[i][j] = true;else mp[i][j] = false;}}void output(){printf(" %d %d\n", mp[0][1] , mp[0][2]);printf("%d %d %d\n" , mp[1][0] , mp[1][1] , mp[1][2]);printf("%d %d\n", mp[2][0] , mp[2][1]);}void input(){for(int i = 0 ; i < 3 ; ++i)for (int j = 0 ; j < 3 ; ++j){if (i + j == 0 || i + j == 4) continue;int x;RD(x);mp[i][j] = x;}encode();}}en , temp;
LL n;
Mat P , Q ;
void solve(){RD(n);en.input();Mat nP = P;
// nP.output();nR.copy(R);
// nR.a[0][1].output();
// printf("N %lld\n" , n);QQ = nR.power(n);
// cout << "DS" << endl;nP = nP * QQ;printf("%lld\n" , nP.a[0][en.hash]);
}
bool inmap(int x , int y){if (x + y == 0) return false;if (x + y == 4) return false;return 0 <= x && x < 3 && 0 <= y && y < 3;
}
int canput(int bi , int x , int y , int d){temp.hash = bi;temp.decode();if (!inmap(x , y) || !inmap(x + dx4[d] , y + dy4[d]) || !inmap(x + dx4[(d + 1) % 4] , y + dy4[(d + 1) % 4])) return -1;if (!temp.mp[x][y] || !temp.mp[x + dx4[d]][y + dy4[d]] || !temp.mp[x + dx4[(d + 1) % 4]][y + dy4[(d + 1) % 4]]) return -1;temp.mp[x][y] = 0;temp.mp[x + dx4[d]][y + dy4[d]] = 0;temp.mp[x + dx4[(d + 1) % 4]][y + dy4[(d + 1) % 4]] = 0;return temp.encode();
}
int takeOut(int bi , int x , int y , int d){temp.hash = bi;temp.decode();temp.mp[x][y] = 0;temp.mp[x + dx4[d]][y + dy4[d]] = 0;temp.mp[x + dx4[(d + 1) % 4]][y + dy4[(d + 1) % 4]] = 0;return temp.encode();
}
bool canput2(int bi , int x , int y , int d , int x1 , int y1 , int d1){temp.hash = bi;temp.decode();if (!inmap(x , y) || !inmap(x + dx4[d] , y + dy4[d]) || !inmap(x + dx4[(d + 1) % 4] , y + dy4[(d + 1) % 4])) return false;if (!temp.mp[x][y] || !temp.mp[x + dx4[d]][y + dy4[d]] || ! temp.mp[x + dx4[(d + 1) % 4]][y + dy4[(d + 1) % 4]]) return false;temp.mp[x][y] = 0;temp.mp[x + dx4[d]][y + dy4[d]] = 0;temp.mp[x + dx4[(d + 1) % 4]][y + dy4[(d + 1) % 4]] = 0;if (!inmap(x1 , y1) || !inmap(x1 + dx4[d1] , y1+ dy4[d1]) || !inmap(x1 + dx4[(d1 + 1) % 4] , y1 + dy4[(d1 + 1) % 4])) return false;if (!temp.mp[x1][y1] || !temp.mp[x1 + dx4[d1]][y1 + dy4[d1]] || ! temp.mp[x1 + dx4[(d1 + 1) % 4]][y1 + dy4[(d1 + 1) % 4]]) return false;temp.mp[x1][y1] = 0;temp.mp[x1 + dx4[d1]][y1 + dy4[d1]] = 0;temp.mp[x1 + dx4[(d1 + 1) % 4]][y1 + dy4[(d1 + 1) % 4]] = 0;return temp.encode() == 0;}
void initialP(){P.init();P.Matn = 1 , P.Matm = 128;for (int i = 0 ; i < 128 ; ++i)for (int j = 0 ; j < 3 ; ++j)for (int k = 0 ; k < 3 ; ++k)for (int d = 0 ; d < 4 ; ++d){int res = canput(i , j , k , d);if (res == 0)++P.a[0][i];}for (int i = 0 ; i < 128 ; ++i)for (int j = 0 ; j < 3 ; ++j)for (int k = 0 ; k < 3 ; ++k)for (int d = 0 ; d < 4 ; ++d)for (int j1 = i ; j1 < 3 ; ++j1)for (int k1 = j ; k1 < 3 ; ++k1)for (int d1 = 0 ; d1 < 4 ; ++d1){bool res = (canput2(i , j , k , d , j1 , k1 , d1));if (res)++P.a[0][i];}
// for (int i = 0 ; i < 128 ; ++i)
// if (P.a[0][i] == 2){
// temp.hash = i;
// temp.decode();
// temp.output();
// }
}
vector< PII > memory[129][129];
bool has(int bi , int bb){int res = bi & bb;return res == bb;
}
int ok[129][129];
bool canPush(int down , int up){
// printf("PRE : %d %d\n" , down , up);if(down + up == 0) {ok[down][up] = 1;return 1;}
// printf("%d\n" , ok[down][up]);if (ok[down][up] != -1) return ok[down][up];// printf("NEX : %d %d\n" , down , up);//if (memory[down][up] != -1) return memory[down][up];for (int i = 0 ; i < 3 ; ++i)for (int j = 0 ; j < 3 ; ++j)for (int d = 0 ; d < 4 ; ++d){int res = canput(down , i , j , d);if (res != -1){int newdown = res;if (canPush(newdown , up)){memory[down][up].PB(MP(newdown , up));//return 1;}}}for (int i = 0 ; i < 3 ; ++i)for (int j = 0 ; j < 3 ; ++j)for (int d = 0 ; d < 4 ; ++d){int res = canput(up , i , j , d);if (res != -1){int newup = res;if (canPush(down , newup)){memory[down][up].PB(MP(down , newup));
// return 1;}}}/**1 24 8 1632 64*/if (has(down , 3) && has(up , 1))if (canPush(down - 3 , up - 1)){memory[down][up].PB(MP(down - 3 , up - 1));}// = 1 ; return 1;}if (has(down , 3) && has(up , 2))if (canPush(down - 3 , up - 2)){memory[down][up].PB(MP(down - 3 , up - 2));}// = 1 ; return 1;}if (has(down , 12) && has(up , 4))if (canPush(down - 12 , up - 4)){memory[down][up].PB(MP(down - 12 , up - 4));}// = 1 ; return 1;}if (has(down , 12) && has(up , 8))if (canPush(down - 12 , up - 8)){memory[down][up].PB(MP(down - 12 , up - 8));}// = 1 ; return 1;}if (has(down , 24) && has(up , 8))if (canPush(down - 24 , up - 8)){memory[down][up].PB(MP(down - 24 , up - 8));}// = 1 ; return 1;}if (has(down , 24) && has(up , 16))if (canPush(down - 24 , up - 16)){memory[down][up].PB(MP(down - 24 , up - 16));}// = 1 ; return 1;}if (has(down , 96) && has(up , 32))if (canPush(down - 96 , up - 32)){memory[down][up].PB(MP(down - 96 , up - 32));}// = 1 ; return 1;}if (has(down , 96) && has(up , 64))if (canPush(down - 96 , up - 64)){memory[down][up].PB(MP(down - 96 , up - 24));}// = 1 ; return 1;}/**1 24 8 1632 64*/if (has(down , 36) && has(up , 4))if (canPush(down - 36 , up - 4)){memory[down][up].PB(MP(down - 36 , up - 4));}// = 1 ; return 1;}if (has(down , 36) && has(up , 32))if (canPush(down - 36 , up - 32)){memory[down][up].PB(MP(down - 36 , up - 32));}// = 1 ; return 1;}if (has(down , 9) && has(up , 1))if (canPush(down - 9 , up - 1)){memory[down][up].PB(MP(down - 9 , up - 1));}// = 1 ; return 1;}if (has(down , 9) && has(up , 8))if (canPush(down - 9 , up - 8)){memory[down][up].PB(MP(down - 9 , up - 8));}// = 1 ; return 1;}if (has(down , 72) && has(up , 8))if (canPush(down - 72 , up - 8)){memory[down][up].PB(MP(down - 72 , up - 8));}// = 1 ; return 1;}if (has(down , 72) && has(up , 64))if (canPush(down - 72 , up - 64)){memory[down][up].PB(MP(down - 72 , up - 64));}// = 1 ; return 1;}if (has(down , 18) && has(up , 2))if (canPush(down - 18 , up - 2)){memory[down][up].PB(MP(down - 18 , up - 2));}// = 1 ; return 1;}if (has(down , 18) && has(up , 16))if (canPush(down - 18 , up - 16)){memory[down][up].PB(MP(down - 18 , up - 16));}// = 1 ; return 1;}/**1 24 8 1632 64*/if (has(up , 3) && has(down , 1))if (canPush(down - 1 , up - 3 )){memory[down][up].PB(MP(down - 1 , up - 3));}// = 1 ; return 1;}if (has(up , 3) && has(down , 2))if (canPush(down - 2 , up - 3)){memory[down][up].PB(MP(down - 2 , up - 3));}// = 1 ; return 1;}if (has(up , 12) && has(down , 4))if (canPush(down - 4 , up - 12)){memory[down][up].PB(MP(down - 4 , up - 12));}// = 1 ; return 1;}if (has(up , 12) && has(down , 8))if (canPush(down - 8 , up - 12)){memory[down][up].PB(MP(down - 8 , up - 12));}// = 1 ; return 1;}if (has(up , 24) && has(down , 8))if (canPush(down - 8 , up - 24)){memory[down][up].PB(MP(down - 8 , up - 24));}// = 1 ; return 1;}if (has(up , 24) && has(down , 16))if (canPush(down - 16 , up - 24)){memory[down][up].PB(MP(down - 16 , up - 24));}// = 1 ; return 1;}if (has(up , 96) && has(down , 32))if (canPush(down - 32 , up - 96)){memory[down][up].PB(MP(down - 32 , up - 96));}// = 1 ; return 1;}if (has(up , 96) && has(down , 64))if (canPush(down - 64 , up - 96)){memory[down][up].PB(MP(down - 64 , up - 96));}// = 1 ; return 1;}/**1 24 8 1632 64*/if (has(up , 36) && has(down , 4))if (canPush(down - 4 , up - 36)){memory[down][up].PB(MP(down - 4 , up - 36));}// = 1 ; return 1;}if (has(up , 36) && has(down , 32))if (canPush(down - 32 , up - 36)){memory[down][up].PB(MP(down - 32 , up - 36));}// = 1 ; return 1;}if (has(up , 9) && has(down , 1))if (canPush(down - 1 , up - 9)){memory[down][up].PB(MP(down - 1 , up - 9));}// = 1 ; return 1;}if (has(up , 9) && has(down , 8))if (canPush(down - 8 , up - 9)){memory[down][up].PB(MP(down - 8 , up - 9));}// = 1 ; return 1;}if (has(up , 72) && has(down , 8))if (canPush(down - 8 , up - 72)){memory[down][up].PB(MP(down - 8 , up - 72));}// = 1 ; return 1;}if (has(up , 72) && has(down , 64))if (canPush(down - 64 , up - 72)){memory[down][up].PB(MP(down - 64 , up - 72));}// = 1 ; return 1;}if (has(up , 18) && has(down , 2))if (canPush(down - 2 , up - 18)){memory[down][up].PB(MP(down - 2 , up - 18));}// = 1 ; return 1;}if (has(up , 18) && has(down , 16))if (canPush(down - 16 , up - 18)){memory[down][up].PB(MP(down - 16 , up - 18));}// = 1 ; return 1;}ok[down][up] = (SZ(memory[down][up]) > 0);return SZ(memory[down][up]) > 0;
}
vector<PII> cmp1 , cmp2;
struct ME{vector<PII> del;ME(){del.clear();}void rush(){sort(ALL(del));}bool operator < (const ME & A) const{cmp1 = del;cmp2 = A.del;sort(ALL(cmp1));sort(ALL(cmp2));//if (SZ(cmp1) != SZ(cmp2)) return SZ(cmp1) < SZ(cmp2);for (int i = 0 ; i < min(SZ(cmp1) , SZ(cmp2)) ; ++i)if (cmp1[i] != cmp2[i])return cmp1[i] < cmp2[i];return false;}bool operator == (const ME & A) const{return (!(*this < A) && !(A < *this));}
};
vector<ME> mycnt;
vector<PII> :: iterator iter;
ME now;
void cnt(int down , int up){
// printf("PRE %d %d\n" , down , up);if(down == 0 && up == 0){mycnt.PB(now);return;}if (ok[down][up] == 0) return;
// printf("CNT: %d %d\n" , down , up);
// cout << SZ(memory[down][up]) << endl;for(int i = 0 ; i < SZ(memory[down][up]) ;++i){int newdown = memory[down][up][i].fi;int newup = memory[down][up][i].se;
// printf("-%d %d\n", newdown , newup);now.del.PB( MP(down - newdown , up - newup) );
// printf("+ %d %d\n" , down - newdown , up - newup);cnt(newdown , newup);iter = now.del.end() - 1;//iter--;
// printf("- %d %d\n" , iter->fi , iter->se);now.del.erase(iter);//( MP(down - newdown , up - newup) );}
}
void initialQ(){Q.init();Q.Matn = 128 , Q.Matm = 128;
// canPush(3 , 127);mycnt.clear();
// cnt(3 , 127);
// sort(ALL(mycnt));
// printf("%d\n" , unique(ALL(mycnt)) - mycnt.begin());return;
// for (int i = 0 ; i < 128 ; ++i)
// for (int j = 0 ; j < 128; ++j)
// canPush(i , j);for (int i = 0 ; i < 128 ; ++i)for (int j = 0 ; j < 128 ; ++j){if (canPush(127 - j , i)){mycnt.clear();cnt(127 - j , i);sort( ALL(mycnt) );Q.a[j][i] = unique(ALL(mycnt)) - mycnt.begin();
//
// printf("<<<<<<<<<<<\n");
// temp.hash = j;printf("%d:\n" , j);temp.decode();temp.output();
// temp.hash = i;printf("%d:\n" , i);temp.decode();temp.output();
// printf(">>>>>>>>>>>\n");
// printf("%d\n" , SZ(mycnt));
// for (int ds = 0 ; ds < SZ(mycnt) ; ++ds){
// for (int Meng = 0 ; Meng < mycnt[ds].del.size() ; ++Meng)
// printf("(%d,%d) " , mycnt[ds].del[Meng].fi , mycnt[ds].del[Meng].se);
// cout << endl;
// }
// cout << endl;
// printf("%d\n" , Q.a[j][i]);}else Q.a[j][i] = 0;}
}
void initialR(){R.init(Q);
}
void init(){memset(ok , -1 , sizeof(ok));for (int i = 0 ; i < 128 ; ++i)for (int j = 0 ; j < 128 ; ++j)memory[i][j].clear();initialP();initialQ();initialR();
// cout << "GG" << endl;
}
int main(){
// freopen("0.in" , "r" , stdin);
// freopen("1.out" , "w" , stdout);init();solve();
}
XLK的代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<vector>
using namespace std;
#define fr(i,n) for(int i=0;i<n;i++)
#define fo(i,n) for(int i=1;i<=n;i++)
#define fe(i,n) for(__typeof(n.begin()) i=n.begin();i!=n.end();i++)
int a[100020],ac;
int v[100020];
long long A[130][130];
long long B[130][130];
int N=1<<7,p=1000000007;
int mk(int x,int y,int z)
{return 1<<x|1<<y|1<<z;
}
void pre()
{int x[]={0,0,1,1,1,2,2};int y[]={1,2,0,1,2,0,1};int r[3][3]={-1,0,1,2,3,4,5,6,-1};int u[3][3]={-1,7,8,9,10,11,12,13,-1};int dx[]={1,0,-1,0};int dy[]={0,1,0,-1};for(int i=0;i<7;i++){int nx=x[i],ny=y[i];for(int i=0;i<4;i++){int qx=nx+dx[i];int qy=ny+dy[i];if(qx>=0&&qy>=0&&qx<3&&qy<3&&r[qx][qy]!=-1){a[ac++]=mk(r[nx][ny],u[nx][ny],r[qx][qy]);a[ac++]=mk(r[nx][ny],u[nx][ny],u[qx][qy]);}int px=nx+dx[i+1&3];int py=ny+dy[i+1&3];if(qx>=0&&qy>=0&&qx<3&&qy<3&&r[qx][qy]!=-1)if(px>=0&&py>=0&&px<3&&py<3&&r[px][py]!=-1){a[ac++]=mk(r[nx][ny],r[px][py],r[qx][qy]);
// a[ac++]=mk(u[nx][ny],u[px][py],u[qx][qy]);} }}
}
void mul(long long a[130][130],long long b[130][130],long long c[130][130])
{long long r[130][130]={};for(int i=0;i<N;i++)for(int k=0;k<N;k++)if(a[i][k])for(int j=0;j<N;j++)r[i][j]=(r[i][j]+a[i][k]*b[k][j])%p;for(int i=0;i<N;i++)for(int j=0;j<N;j++)c[i][j]=r[i][j];
}
int main()
{N++; pre();
// cout << ac << endl;v[0]=1;for(int j=0;j<ac;j++)for(int i=0;i<1<<14;i++)if(v[i])if((i&a[j])==0)v[i|a[j]]++;int t,n;for(;~scanf("%d",&n);){memset(A,0,sizeof A);memset(B,0,sizeof B);A[0][0]=1;for(int i=0;i<N-1;i++)for(int j=0;j<N-1;j++)B[i][j]=v[i<<7|(127^j)];n++;int w=0;for(int i=0;i<7;i++){int d;scanf("%1d",&d);w=w*2+1-d;}B[w][N-1]=1;B[N-1][N-1]=1;for(;n;n>>=1){if(n&1)mul(A,B,A);mul(B,B,B);}if(A[0][N-1]==0)puts("No way");elseprintf("%d\n",(int)A[0][N-1]);}return 0;
}
Krites 的代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <cmath>using namespace std;#ifndef ONLINE_JUDGE
#define DEBUG(a) cout << #a"= " << a << endl
#else
#define DEBUG(a)
#endif
typedef long long LL;
const int maxn = 1 << 7;
const int mod = (int)1e9 + 7;struct Martix {LL C[maxn][maxn];Martix() { memset(C, 0, sizeof(C)); }void init() { memset(C, 0, sizeof(C)); }void initC() { for (int i = 0; i < maxn; ++i) C[i][i] = 1; }Martix operator*(const Martix& rhs) const {Martix res;for (int i = 0; i < maxn; ++i) {for (int j = 0; j < maxn; ++j) {for (int k = 0; k < maxn; ++k) {res.C[i][j] += C[i][k] * rhs.C[k][j];res.C[i][j] %= mod;}}}return res;}Martix operator+(const Martix& rhs) const {Martix res;for (int i = 0; i < maxn; ++i) {for (int j = 0; j < maxn; ++j) {res.C[i][j] = C[i][j] + rhs.C[i][j];if (res.C[i][j] >= mod) res.C[i][j] -= mod;}}return res;}
};Martix start, inc;
int Kr[8][4] = {{3, 9}, {3, 6}, {6, 12}, {9, 12, 24, 72},{24, 48}, {48, 96}, {72, 96}
};
int Sr[] = {7, 11, 13, 14, 25, 56, 76, 88, 104, 112
};
void dfs(int deep, int s, int ps) {if (deep == 17) {++start.C[ps^(maxn - 1)][s ^ (maxn - 1)]; return;}if (deep < 7) {int sz = (deep == 3) ? 4 : 2;for (int i = 0; i < sz; ++i) {if ((s & Kr[deep][i]) == Kr[deep][i])dfs(deep + 1, s ^ Kr[deep][i], ps ^ (1 << deep));}dfs(deep + 1, s, ps);} else {if ((s & Sr[deep - 7]) == Sr[deep - 7]) dfs(deep + 1, s ^ Sr[deep - 7], ps);dfs(deep + 1, s, ps);}
}Martix powMartix(Martix base, int N) {Martix res; res.initC();while (N) {if (N & 1) res = res * base;base = base * base;N >>= 1;}return res;
}Martix sumMartix(int N) {if (N == 0) {return inc;} else if (N == 1) {return start;} else if (N % 2 == 0) {Martix tmp = powMartix(start, N >> 1);tmp = tmp + inc;return tmp * sumMartix(N >> 1);} else {Martix tmp = powMartix(start, N);return tmp + sumMartix(N - 1);}
}void solved(int nT) {char s[12]; int N;scanf("%d", &N);int rs = 0;scanf("%s", s);if (s[0] == '1') rs |= 1;if (s[1] == '1') rs |= 2;scanf("%s", s);if (s[0] == '1') rs |= 16;if (s[1] == '1') rs |= 8;if (s[2] == '1') rs |= 4;scanf("%s", s);if (s[0] == '1') rs |= 32;if (s[1] == '1') rs |= 64;Martix result = sumMartix(N);LL res = result.C[maxn - 1][rs];if (res == 0) puts("No way");else printf("%lld\n", res);
}int main() {dfs(0, maxn - 1, 0);inc.initC();int T = 1;//scanf("%d", &T);for (int nT = 1; nT <= T; ++nT) {solved(nT);}return 0;
}
BSBandme 的代码:
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <sstream>using namespace std;typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vl;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;const double pi = acos(0.0) * 2.0;
const double eps = 1e-12;
const int step[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b) {return a > b ? a : b;}
template <class T> inline T min1(T a, T b) {return a < b ? a : b;}
template <class T> inline T gcd1(T a, T b) {if(a < b) swap(a, b);if(a % b == 0) return b;return gcd1(b, a % b);
}
template <class T> inline T lb(T num) {return num & (-num); }
inline int jud(double a, double b){if(abs1(a - b) < eps) return 0;if(a < b) return -1;return 1;
}
template <class t>
inline int find(int val, t *a, int na, bool f_small = 1, bool f_lb = 1){if(na == 1) return 0;int be = 0, en = na - 1;if(a[0] <= a[na - 1]){if(f_lb == 0) while(be < en){int mid = (be + en + 1) / 2;if(jud(a[mid], val) != 1) be = mid;else en = mid - 1;}else while(be < en){int mid = (be + en) / 2;if(jud(a[mid], val) != -1) en = mid;else be = mid + 1;}if(f_small && a[be] > val && be != 0) be--;if(!f_small && a[be] < val && be != na - 1) be++;} else {if(f_lb) while(be < en){int mid = (be + en + 1) / 2;if(jud(a[mid], val) != -1) be = mid;else en = mid - 1;}else while(be < en){int mid = (be + en) / 2;if(jud(a[mid], val) != 1) en = mid;else be = mid + 1;}if(!f_small && a[be] < val && be != 0) be--;if(f_small && a[be] > val && be != na - 1) be++;}return be;
}
inline int bitnum(ull nValue){nValue = ((0xaaaaaaaaaaaaaaaaull & nValue)>>1) + (0x5555555555555555ull & nValue);nValue = ((0xccccccccccccccccull & nValue)>>2) + (0x3333333333333333ull & nValue);nValue = ((0xf0f0f0f0f0f0f0f0ull & nValue)>>4) + (0x0f0f0f0f0f0f0f0full & nValue);nValue = ((0xff00ff00ff00ff00ull & nValue)>>8) + (0x00ff00ff00ff00ffull & nValue);nValue = ((0xffff0000ffff0000ull & nValue)>>16) + (0x0000ffff0000ffffull & nValue);nValue = ((0xffffffff00000000ull & nValue)>>32) + (0x00000000ffffffffull & nValue);return nValue;
}
long long pow(long long n, long long m, long long mod = 0){long long ans = 1;long long k = n;while(m){if(m & 1) {ans *= k;if(mod) ans %= mod;}k *= k;if(mod) k %= mod;m >>= 1;}return ans;
}const int mod = 1000000007;
template <typename t> struct matrix{const static int maxn = 130;int row, col;t mat[maxn][maxn];matrix(int r = 0, int c = 0){row = r; col = c;for(int i = 0; i < row; i++) for(int j = 0; j < col; j++) mat[i][j] = 0;}bool danweiju(){if(row != col) return 0;for(int i = 0; i < row; i++) for(int j = 0; j < col; j++) mat[i][j] = bool (i == j);return 1;}matrix operator * (const matrix& b) const{int i, j, k;matrix <t> c(row, b.col);memset(c.mat, 0, sizeof(c.mat));for (i = 0; i < c.row; i++) for (k = 0; k < col; k++)if(mat[i][k])for (j = 0; j < c.col; j++){c.mat[i][j] += mat[i][k] * b.mat[k][j];c.mat[i][j] %= mod;}return c;}matrix operator + (const matrix& b) const{matrix <t> c(max1(row, b.row), max1(col, b.col));for(int i = 0; i < c.row; i++) for(int j = 0; j < c.col; j++){t a = 0; if(i < row && j < col) a = mat[i][j];t b1 = 0; if(i < b.row && j < b.col) b1 = b.mat[i][j];c.mat[i][j] = a + b1;c.mat[i][j] %= mod;}return c;}matrix operator - (const matrix& b) const{matrix <t> c(max1(row, b.row), max1(col, b.col));for(int i = 0; i < c.row; i++) for(int j = 0; j < c.col; j++){t a = 0; if(i < row && j < col) a = mat[i][j];t b1 = 0; if(i < b.row && j < b.col) b1 = b.mat[i][j];c.mat[i][j] = a - b1;}return c;}inline void operator = (const matrix & b){memcpy(mat, b.mat, sizeof(mat));col = b.col; row = b.row;}matrix pow(int n){matrix <t> ans(row, col), temp = *this;ans.danweiju();while(n){if(n & 1) ans = ans * temp;temp = temp * temp;n >>= 1;}return ans;}int inv(){int i, j, k, is[maxn], js[maxn];double t1;if (row != col) return 0;for(k = 0; k < row; k++){for(t1 = 0,i = k; i < row; i++) for(j = k; j < row; j++)if(fabs(mat[i][j]) > t1)t1=fabs(mat[is[k] = i][js[k] = j]);if (fabs(t1 - 0) < 1e-9) return 0;if (is[k] != k) for(j = 0; j < row; j++)t1 = mat[k][j], mat[k][j] = mat[is[k]][j], mat[is[k]][j] = t1;if (js[k] != k) for (i = 0; i < row; i++)t1 = mat[i][k], mat[i][k] = mat[i][js[k]], mat[i][js[k]] = t1;mat[k][k] = 1 / mat[k][k];for(j = 0; j < row; j++) if (j != k)mat[k][j] *= mat[k][k];for (i = 0; i < row; i++) if (i != k)for (j = 0; j < row; j++) if (j != k)mat[i][j] -= mat[i][k] * mat[k][j];for (i = 0;i < row; i++) if (i != k)mat[i][k] *= -mat[k][k];}for (k = row-1; k >= 0; k--){for (j = 0; j < row; j++) if (js[k] != k)t1 = mat[k][j], mat[k][j] = mat[js[k]][j], mat[js[k]][j]=t1;for (i = 0; i < row; i++) if (is[k] != k)t1 = mat[i][k], mat[i][k] = mat[i][is[k]], mat[i][is[k]] = t1;}return 1;}double det(){int i, j, k, sign = 0;double b[maxn][maxn], ret = 1, t1;if (row != col) return 0;for (i = 0; i < row; i++) for (j = 0; j < col; j++)b[i][j] = mat[i][j];for (i = 0; i < row; i++){if (fabs(b[i][i] - 0) < 1e-9){for (j = i + 1; j < row; j++)if (fabs(b[j][i] - 0) > 1e-9) break;if (j == row) return 0;for (k = i; k < row; k++)t1 = b[i][k], b[i][k] = b[j][k], b[j][k] = t1;sign++;}ret *= b[i][i];for (k = i + 1; k < row; k++) b[i][k] /= b[i][i];for (j = i + 1; j < row; j++) for (k = i + 1; k < row; k++)b[j][k] -= b[j][i] * b[i][k];}if (sign & 1) ret = -ret;return ret;}
};const int trans[42][2] = {{1, 3}, {1, 9}, {2, 3}, {2, 18}, {4, 12}, {4, 36}, {8, 12}, {8, 72}, {8, 9}, {8, 24}, {16, 24}, {16, 18}, {32, 36}, {32, 96}, {64, 96}, {64, 72},{3, 1}, {3, 2}, {12, 4}, {12, 8}, {24, 8}, {24, 16}, {96, 32}, {96, 64}, {36, 4}, {36, 32}, {9, 1}, {9, 8}, {72, 8}, {72, 64}, {18, 2}, {18, 16}, {11, 0}, {19, 0}, {13, 0}, {44, 0}, {76, 0}, {25, 0}, {26, 0}, {88, 0}, {100, 0}, {104, 0}};
vi wh[100];
ll dp[128][128];
bool f[128][128];
pii q[1 << 15];
int lq, rq;
int ncase, n;
char str[10];
matrix <ll> m(128, 128);int main(){for(int i = 0; i < 42; i++){int k = lb(trans[i][0]);wh[k].push_back(i);}for(int i = 0; i < 128; i++){memset(dp, 0, sizeof(dp));memset(f, 0, sizeof(f));dp[i][0] = 1; rq = 1; f[i][0] = 1;q[lq = 0] = make_pair(i, 0);for(; rq != lq; ){int wh1 = lb(q[lq].first + 1);for(int j = 0; j < (int)wh[wh1].size(); j++){if((q[lq].first & trans[wh[wh1][j]][0]) || (q[lq].second & trans[wh[wh1][j]][1])) continue;pii p;p.first = q[lq].first | trans[wh[wh1][j]][0];p.second = q[lq].second | trans[wh[wh1][j]][1];dp[p.first][p.second] += dp[q[lq].first][q[lq].second];if(p.first != 127 && f[p.first][p.second] == 0){f[p.first][p.second] = 1;q[rq++] = p;}}lq++;}for(int j = 0; j < 128; j++) m.mat[i][j] = dp[127][j];}while(scanf("%d", &n) != -1){for(int i = 0; i < 7; i++)while(str[i] != 48 && str[i] != 49)scanf("%c", str + i);int num = 0;for(int i = 0; i < 7; i++) num += (str[i] - 48) << i;m = m.pow(n - 1);ll ans = m.mat[0][num];for(int i = 0; i < 127; i++){for(int j = 32; j < 42; j++)if(((i & trans[j][0]) == 0) && ((i | trans[j][0]) == num)){ans += m.mat[0][i];break;}}if(num == 127) ans += m.mat[0][2] + m.mat[0][8] + m.mat[0][32];cout << num << ' ' << ans % mod << endl;}return 0;
}
总结:
总之我还是太弱了啊T_T。
XLK 好强啊T_T
孟竹祝你寒假快乐~love you
祝大家寒假开心,新春快乐
这篇关于Contest - ACdream原创群赛の妹子的假期生活 解题报告的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!