题目分析:
题目要求前后缀相同,把串反过来之后是一个很明显的卷积的形式。这样我们可以完成初步判断(即可以知道哪些必然不行)。
然后考虑一下虽然卷积结果成立,但是存在问号冲突的情况。
箭头之间应当不存在1。不然就和图上所画的一样。注意到它每隔len个跳一次,所以相当于调和级数,利用原有信息判断即可。
字符串转化的方式有很多种。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = (1<<19)+5; 5 6 const int mod = 998244353; 7 const int gg = 3; 8 9 char str[maxn]; 10 11 int n,m,len,a[maxn<<1],b[maxn<<1],ord[maxn<<1]; 12 13 int f[maxn<<1],iv; 14 15 int fast_pow(int now,int pw){ 16 int ans = 1,dd = now,bit = 1; 17 while(bit <= pw){ 18 if(bit & pw) {ans = (1ll*ans*dd)%mod;} 19 dd = (1ll*dd*dd)%mod; 20 bit<<=1; 21 } 22 return ans; 23 } 24 25 void fft(int *d,int dr){ 26 for(register int i=0;i<m;i++) if(i < ord[i]) swap(d[i],d[ord[i]]); 27 for(register int i=1;i<m;i<<=1){ 28 int wn = fast_pow(gg,(mod-1)/(2*i)); 29 if(dr == -1) wn = fast_pow(wn,mod-2); 30 for(register int j=0;j<m;j+=(i<<1)){ 31 for(register int k=0,w=1;k<i;k++,w = (1ll*w*wn)%mod){ 32 int x = d[j+k],y = (1ll*w*d[j+k+i])%mod; 33 d[j+k] = x+y; d[j+k] >=mod?d[j+k]-=mod:1; 34 d[j+k+i] = x-y; 35 d[j+k+i] < 0?d[j+k+i]+=mod:1; 36 } 37 } 38 } 39 if(dr == -1){ 40 for(register int i=0;i<m;i++) d[i] = (1ll*d[i]*iv)%mod; 41 } 42 } 43 44 void work(){ 45 int n = strlen(str);m = 1; 46 while(m < 2*n){m<<=1;len++;} iv = fast_pow(m,mod-2); 47 for(register int i=0;i<m;i++) ord[i] = (ord[i>>1]>>1)+((i&1)<<len-1); 48 49 for(register int i=0;i<n;i++) { 50 if(str[i] == '0') a[i] = 1; 51 else if(str[i] == '1') b[n-i-1] = 1; 52 } 53 54 fft(a,1); fft(b,1); 55 for(register int i=0;i<m;i++) { 56 f[i] = (1ll*a[i]*b[i])%mod; 57 } 58 59 memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); 60 61 for(register int i=0;i<n;i++) { 62 if(str[i] == '1') a[i] = 1; 63 else if(str[i] == '0') b[n-i-1] = 1; 64 } 65 66 fft(a,1); fft(b,1); 67 for(register int i=0;i<m;i++) { 68 f[i] += (1ll*a[i]*b[i])%mod; if(f[i] >mod)f[i]-=mod; 69 } 70 71 fft(f,-1); 72 73 for(register int i=0;i<n-1;i++){ 74 int now = n-1-i; 75 for(register int j=i-now;j>=0;j-=now){ 76 f[i] |= f[j]; 77 } 78 } 79 80 long long ans = 0; 81 for(register int i=1;i<=n;i++){ 82 ans ^= (1ll*(f[i-1]==0)*i*i); 83 } 84 printf("%lld",ans); 85 } 86 87 int main(){ 88 scanf("%s",str); 89 work(); 90 return 0; 91 }