ZROI2018提高day5t3
分析
我们可以根据性质将这个序列构造成一个环:0,a[1~n],0,a[n~1]
这中间的0是为了起间隔作用的。
我们又知道b[i]=a[i-1]^a[i+1]
c[i]=b[i-1]^b[i+1]=a[i-2]^a[i]^a[i]^a[i+2]=a[i-2]^a[i+2]
所以如果这个环进化了2d次,则c[i]=a[i-2d]^a[i+2d]
所以我们二进制拆分一下就可以了。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
const long long LOG = 60;
char s[200100];
long long a[200100],b[200100];
int main(){
long long n,m,t,i,j,k;
scanf("%lld%lld",&t,&n);
scanf("%s",s);
m=2*n+2;
a[0]=0;
for(i=1;i<=n;i++)a[i]=s[i-1]-'0';
a[n+1]=0;
for(i=n+2;i<=2*n+1;i++)a[i]=a[n-(i-n-1)+1];
for(i=LOG;i>=0;i--)
if((1ll<<i)&t){
for(j=0;j<m;j++)
b[j]=a[(j-(1ll<<i)%m+m)%m]^a[(j+(1ll<<i)%m)%m];
for(j=0;j<m;j++)a[j]=b[j];
}
for(i=1;i<=n;i++)printf("%lld",a[i]);
return 0;
}