Bzoj1511---OKR-Periods of Words(KMP)

Posted wangyh1008

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bzoj1511---OKR-Periods of Words(KMP)相关的知识,希望对你有一定的参考价值。

(传送门)

技术分享图片

大意:对于给定串的每个前缀i,求最长的,使这个字符串重复两边能覆盖原前缀i的前缀(就是前缀i的一个前缀),求所有的这些“前缀的前缀”的长度和

利用 p 的性质:前缀 i 的长度为 p[i] 的前缀和后缀是相等的

这说明:如果i有一个公共前后缀长度为j,那么这个前缀i就有一个周期为i-j

于是我们先预处理p数组,然后再把p数组更新变成最小公共前后缀。最后跑一遍统计答案即可。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cstdlib>
 7 using namespace std;
 8 int p[2000005],n;
 9 char st[2000005];
10 void pre()
11 {
12     p[0]=0; int j=0;
13     for (int i=1; i<=n; i++){
14         while (j>0 && st[j+1]!=st[i+1]) j=p[j];
15         if (st[j+1]==st[i+1]) j++;
16         p[i+1]=j;
17     }
18 }
19 int main()
20 {
21     scanf("%d
",&n);
22     cin>>st+1;
23     pre();
24     int ans=0;
25     for (int i=1; i<=n; i++){
26         if (!p[i]) continue;
27         if (p[p[i]]) p[i]=p[p[i]];
28     }
29     for (int i=1; i<=n; i++) if (p[i])ans+=i-p[i];
30     cout<<ans<<endl;
31     return 0;
32 }

miao~~~

以上是关于Bzoj1511---OKR-Periods of Words(KMP)的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 3546: [ONTAK2010]Life of the Party

BZOJ3417Poi2013 Tales of seafaring 分层图BFS

bzoj 1272: [BeiJingWc2008]Gate Of Babylon

BZOJ 1272 1272: [BeiJingWc2008]Gate Of Babylon (容斥原理+卢卡斯定理)

bzoj 1511: [POI2006]OKR-Periods of Wordskmp

最小生成树BZOJ1682[Usaco2005 Mar]-Out of Hay 干草危机