BZOJ3670: [Noi2014]动物园

KMP
一开始的想法是二分next然后nlogn
妥妥的T了
后来看大神题解发现时可以O(n)建造二倍的next的
自己居然想不到这么做。。。
马上要省选了感觉自己智商不够啊

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

int next[1000004];
int next2[1000004];
int data[1000004];
int data2[1000004];
int  pos[1000004];
int r[1000004];
const
   int mod=1000000007;
char a[1000004];
int main()
{
    int T;
scanf("%d",&T);
while(T--)
{
  scanf("%s",a);
  int i,j,k,l,n;
  n=strlen(a);
  next[0]=-1;
  data[0]=1;
   for(i=1;i<n;i++)
    {
       j=next[i-1];
       while(j!=-1&&a[j+1]!=a[i])j=next[j];
       if(a[j+1]!=a[i])data[i]=1,next[i]=-1;
       else next[i]=j+1,data[i]=data[j+1]+1;    
   } 
  next2[0]=-1;
  data2[0]=0;
   for(i=1;i<n;i++)
    {
       j=next2[i-1];
       l=i-1>>1;
       while(j!=-1&&(j>=l||a[j+1]!=a[i])) 
       j=next[j];
       if(a[j+1]!=a[i])
          data2[i]=0,next2[i]=-1;
       else 
          next2[i]=j+1,data2[i]=data[j+1];  
   } 
    long long ans=1;
    for(i=0;i<n;i++)
       ans*=data2[i]+1,ans%=mod;
    printf("%lld\n",ans);
}

   return 0;
}

你可能感兴趣的:(KMP)