2017.2.18[codevs3319][bzoj3670]NOI2014D2T1动物园
题目不贴
这题真的想直接打正解
思路:跟KMP一毛一样……只是特判一下是否大于中间位置,用dp思想记录答案
第一次提交:爆零全WA……不拍的后果……思路还是不够清晰
第二次提交:50分,T了一半……
第三次提交:看了题解发现自己的解法真的是正解……于是疯狂省常……然而还是50分……
第四次提交:终于A了……听ljq大神的意见加了一个鬼畜的剪枝保证了另外的一个KMP一直在L/2以内跑……强力省长
AC总时间耗费: 285ms
总结:
1)加快做题速度
2)以后要慢慢习惯卡常……
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #define N 1000010 7 #define RG register 8 #define MO 1000000007 9 using namespace std; 10 typedef long long LL; 11 LL ans; 12 char c[N]; 13 int T,n,last1,last2,nex[N],hold[N]; 14 inline int gi(){ 15 RG int x=0;RG char c=getchar(); 16 while(c<'0'||c>'9') c=getchar(); 17 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 18 return x; 19 } 20 inline void work(){ 21 scanf("%s",c+1); 22 n=strlen(c+1); 23 memset(nex,0,sizeof(nex)); 24 memset(hold,0,sizeof(hold)); 25 ans=1;last1=last2=0;hold[1]=1; 26 if(n>1) 27 for (RG int i=2;i<=n;++i){ 28 while(last1&&c[last1+1]!=c[i]) last1=nex[last1]; 29 if(c[last1+1]==c[i]) ++last1; 30 nex[i]=last1; 31 hold[i]=hold[last1]+1; 32 while(last2&&c[last2+1]!=c[i]) last2=nex[last2]; 33 if(c[i]==c[last2+1]) ++last2; 34 while(last2>i>>1) last2=nex[last2]; 35 ans=ans*(LL)(hold[last2]+1)%MO; 36 } 37 printf("%lld\n",(ans+MO)%MO); 38 } 39 int main(){ 40 T=gi(); 41 while(T--) work(); 42 return 0; 43 }