[CCC 2016] 生命中的圆
有这么一类题,它让你求一个0/1环经过T轮周围异或过程之后的样子。
周围异或即 a[i][k] = a[i-1][k-1] ^ a[i-1][k+1] ,其中第一维表示轮数,第二维表示位置。
千万不要往组合数二项式定理想,因为这种题就是个套路。。。。。。
我们发现 ,经过 2^j轮之后,a[i][k] = a[i-2^j][k-2^j] ^ a[i-2^j][k+2^j],至于证明可以尝试画图&数学归纳。
显然周围异或的过程是满足结合律的,所以我们直接倍增即可。
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=100005; int s[2][N],n,now,pre; ll T; inline void read(){ char ch=getchar(); while(ch!='0'&&ch!='1') ch=getchar(); for(int i=1;i<n;i++,ch=getchar()) s[0][i-1]=ch-'0'; s[0][n-1]=ch-'0'; } inline int add(int x,int y){ x+=y; return x>=n?x-n:x;} int main(){ scanf("%d%lld",&n,&T); read(); for(int i=1,l,r;T;T>>=1,i=add(i,i)) if(T&1){ pre=now,now^=1; l=n-i,r=i; if(l==n) l=0; for(int j=0;j<n;j++,l=add(l,1),r=add(r,1)) s[now][j]=s[pre][l]^s[pre][r]; } for(int i=0;i<n;i++) putchar(s[now][i]==1?'1':'0'); return 0; }
我爱学习,学习使我快乐