BZOJ3670: [Noi2014]动物园
2018-01-08 09:29
302 查看
t<=5次询问每次问一个<=1e6的串的$\sum_{i=1}^{n} (num_i+1)$,其中num[i]表示既是前缀i的前缀又是前缀i的后缀且这两部分不重叠的子串的数量。
方法一:在KMP树上倍增!吃枣药丸+tle+制杖
方法二:开另一个数组记下每个点在KMP树中的深度,另外开一个指针记下“前后不重叠”的匹配不就完了。。
1 #include<string.h> 2 #include<stdlib.h> 3 #include<stdio.h> 4 //#include<assert.h> 5 #include<algorithm> 6 //#include<iostream> 7 using namespace std; 8 9 int t,n; 10 #define maxn 1000011 11 char s[maxn];int fail[maxn],cnt[maxn]; 12 const int mod=1e9+7; 13 int main() 14 { 15 scanf("%d",&t); 16 while (t--) 17 { 18 scanf("%s",s+1); n=strlen(s+1); 19 int f1=0,f2=0; fail[1]=0; cnt[0]=-1; cnt[1]=0; 20 int ans=1; 21 for (int i=2;i<=n;i++) 22 { 23 while (f1 && s[i]!=s[f1+1]) f1=fail[f1]; 24 if (s[i]==s[f1+1]) f1++; 25 fail[i]=f1; cnt[i]=cnt[f1]+1; 26 27 while (f2 && s[i]!=s[f2+1]) f2=fail[f2]; 28 if (s[i]==s[f2+1]) f2++; 29 while (f2 && f2*2>i) f2=fail[f2]; 30 ans=1ll*ans*(cnt[f2]+2)%mod; 31 } 32 printf("%d\n",ans); 33 } 34 return 0; 35 }View Code
相关文章推荐
- BZOJ3670: [Noi2014]动物园(DP)
- bzoj3670:NOI2014 动物园
- BZOJ3670: [Noi2014]动物园
- BZOJ3670 [Noi2014]动物园 解题报告【字符串】【KMP】
- BZOJ3670(Noi2014)[动物园]--KMP
- bzoj3670【NOI2014】动物园
- bzoj3670 [Noi2014]动物园 kmp
- [KMP fail树] BZOJ3670: [Noi2014]动物园
- BZOJ3670: [Noi2014]动物园(洛谷P2375)
- 【NOI2014】动物园 kmp
- 【bzoj3670】[Noi2014]动物园 KMP
- 字符串(KMP):BZOJ 3670 [Noi2014]动物园
- BZOJ 3670: [Noi2014]动物园 KMP题解
- bzoj 3670: [Noi2014]动物园
- bzoj 3670: [Noi2014]动物园
- BZOJ 3670 NOI 2014 动物园 变形KMP
- BZOJ 3670: [Noi2014]动物园 KMP
- BZOJ-3670: [Noi2014]动物园
- BZOJ3670 [Noi2014]动物园 【KMP计数】
- 【省选专题二】字符串 jzoj 3756【NOI2014】动物园