bzoj 2528: [Poi2011]Periodicity【kmp+构造】
神仙构造,做不来做不来
详见:http://vfleaking.blog.163.com/blog/static/174807634201329104716122/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=200005;
int T,n,ne[N],p[N],cnt,a[N],I,J;
char s[N];
void get()
{
while(1)
{
if(J==0||a[I]==a[J])
{
I++;J++;
ne[I]=J;
break;
}
else
J=ne[J];
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%s",s+1);
n=strlen(s+1);
int i=1,j=0;
ne[1]=0;
while(i<=n)
{
if(j==0||s[i]==s[j])
{
i++;j++;
ne[i]=j;
}
else j=ne[j];
}
i=n+1;
cnt=0;
while(i!=1)
{
cnt++;
p[cnt]=i-1;
i=ne[i];
}
for(int i=1;i<=cnt/2;i++)
swap(p[i],p[cnt+1-i]);
I=2;J=1;
if(p[1]==1)
a[1]=0;
else
{
a[1]=0;
for(int i=2;i<p[1];i++)
a[i]=0,get();
a[p[1]]=1,get();
}
for(int i=2;i<=cnt;i++)
{
if(p[i]<=2*p[i-1])
{
for(int j=p[i-1]+1;j<=p[i];j++)
a[j]=a[j-p[i]+p[i-1]],get();
}
else
{
for(int j=p[i-1]+1;j<p[i]-p[i-1];j++)
a[j]=0,get();
int ii=I,jj=J;
a[p[i]-p[i-1]]=0;get();
if(ne[I]!=1&&(p[i]-p[i-1])%(I-ne[I])==0)
{
I=ii;J=jj;
a[p[i]-p[i-1]]=1;
get();
}
for(int j=p[i]-p[i-1]+1;j<=p[i];j++)
a[j]=a[j-p[i]+p[i-1]],get();
}
}
for(i=1;i<=n;i++)
printf("%d",a[i]);
puts("");
}
return 0;
}