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;
}
原文地址:https://www.cnblogs.com/yzxverygood/p/9699596.html