概述
传送门
题解:
瞎JB猜了个结论居然是对的,看了题解知道为什么对了。
我们考虑先做模糊串匹配,那么长度不大于 n2 n 2 的串只需要匹配上就行了。
否则我们判断他的每一个周期子串是否能作前缀即可。 原因是如果有非法的必然是: 0→?→?→1 0 → ? → ? → 1 类似的情况,而他的周期子串也会有这种情况直到直接出现 0→1 0 → 1 ,我们跳每一个周期子串判一下就好了。
根据调和级数,时间复杂度 O(nlogn) O ( n log n ) 。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod=998244353, G=3;
inline int add(int x,int y) {return (x+y>=mod) ? (x+y-mod) : (x+y);}
inline int dec(int x,int y) {return (x-y<0) ? (x-y+mod) : (x-y);}
inline int mul(int x,int y) {return (LL)x*y%mod;}
inline int power(int a,int b,int rs=1) {for(;b;b>>=1,a=mul(a,a)) if(b&1) rs=mul(rs,a); return rs;}
inline int cinv(int a) {return power(a,mod-2);}
const int N=5e5+50;
char s[N];
int n,ok[N],A[N*8],B[N*8],w[N*8],pos[N*8],k;
inline void init(int nn) {
for(k=1;k<=nn;k<<=1);
for(int i=1;i<k;i++) pos[i]=(i&1) ? ((pos[i>>1]>>1)^(k>>1)) : (pos[i>>1]>>1);
}
inline void dft(int *a,int o=1) {
for(int i=1;i<k;i++) if(pos[i]>i) swap(a[pos[i]],a[i]);
for(int bl=1;bl<k;bl<<=1) {
int tl=bl<<1, wn=power(G,(mod-1)/tl);
w[0]=1; for(int i=1;i<bl;i++) w[i]=mul(w[i-1],wn);
for(int bg=0;bg<k;bg+=tl)
for(int j=0;j<bl;j++) {
int &t1=a[bg+j],&t2=a[bg+j+bl],t=mul(t2,w[j]);
t2=dec(t1,t); t1=add(t1,t);
}
}
if(!~o) {
const int inv=power(k,mod-2);
for(int i=0;i<k;i++) a[i]=mul(a[i],inv);
}
}
inline void mul(int *a,int *b,int *c) {
dft(a); dft(b);
for(int i=0;i<k;i++) c[i]=mul(a[i],b[i]);
dft(c,-1); reverse(c+1,c+k);
}
int main() {
scanf("%s",s); n=strlen(s);
for(int i=0;i<n;i++) A[i]=(s[i]=='0'), B[n-i-1]=(s[i]=='1');
init(2*n); mul(A,B,A);
for(int i=1;i<=n/2;i++)
ok[i]=(!A[i-1] && !A[2*n-i-1]);
for(int i=n/2+1;i<n;i++) {
ok[i]=(!A[i-1] && !A[2*n-i-1]);
int len=n-i, t=i-len;
while(t>0 && ok[i]) ok[i]&=ok[t], t-=len;
}
LL ans=0;
for(int i=1;i<n;i++) if(ok[i]) ans^=((LL)i*i);
ans^=(LL)n*n; cout<<ans<<'n';
}
最后
以上就是犹豫飞机为你收集整理的LOJ#6436. 「PKUSC2018」神仙的游戏的全部内容,希望文章能够帮你解决LOJ#6436. 「PKUSC2018」神仙的游戏所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复