杭电acm3336
http://acm.hdu.edu.cn/showproblem.php?pid=3336
这题运用了next函数的性质,next[n],其实就是求从前往后数的字符串和从后往前数的字符串完全对应的最长位数(从后数和从前数不能完全相同,即去掉其本身);
将出现次数相同的next依次累加,最后汇总(记得加上每一个子串都有本身出现了的一次),这里使用的next函数是以next[0]=-1开始的
苦逼……next[0]=0的写法还没研究出来
View Code
#include<stdio.h> #include<string.h> #define mod 10007 int next[200010],sum[200010]; char s[200010]; void pre(int n) { int i,j=-1; next[0]=-1; i=0; while(s[i]) { if(j==-1||s[i]==s[j]) { i++; j++; next[i]=j; } else j=next[j]; } } int main() { int t,n,i,ss; char c[10]; scanf("%d",&t); while(t--) { ss=0; scanf("%d",&n); gets(c); scanf("%s",s); pre(n); for(i=0;i<200001;i++) sum[i]=0; for(i=1;i<=n;i++) sum[next[i]]=(sum[next[i]]+1)%mod; for(i=1;i<=n;i++) ss=(ss+sum[i]+1)%mod; printf("%d\n",ss); } return 0; }
#include<stdio.h> #include<string.h> #define mod 10007 int next[200010],sum[200010]; char s[200010]; void pre(int n) { int i,j=-1; next[0]=-1; i=0; while(s[i]) { if(j==-1||s[i]==s[j]) { i++; j++; next[i]=j; } else j=next[j]; } } int main() { int t,n,i,ss; char c[10]; scanf("%d",&t); while(t--) { ss=0; scanf("%d",&n); gets(c); scanf("%s",s); pre(n); for(i=0;i<200001;i++) sum[i]=0; for(i=1;i<n;i++) sum[next[i]]=(sum[next[i]]+1)%mod; for(i=1;i<n;i++) ss=(ss+sum[i]+1)%mod; printf("%d\n",ss); } return 0; }


浙公网安备 33010602011771号