ZROI2018提高day5t3

时间:2023-03-09 14:24:52
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 = ;
char s[];
long long a[],b[];
int main(){
long long n,m,t,i,j,k;
scanf("%lld%lld",&t,&n);
scanf("%s",s);
m=*n+;
a[]=;
for(i=;i<=n;i++)a[i]=s[i-]-'';
a[n+]=;
for(i=n+;i<=*n+;i++)a[i]=a[n-(i-n-)+];
for(i=LOG;i>=;i--)
if((1ll<<i)&t){
for(j=;j<m;j++)
b[j]=a[(j-(1ll<<i)%m+m)%m]^a[(j+(1ll<<i)%m)%m];
for(j=;j<m;j++)a[j]=b[j];
}
for(i=;i<=n;i++)printf("%lld",a[i]);
return ;
}