模板题 + KMP + 求最小循环节 --- HDU 3746 Cyclic Nacklace
时间:
2015-07-27 22:35:40
阅读:
131
评论:
收藏:
0
[点我收藏+]
标签:
-----------------------
-----------------------
k m x j i
由上,next[i]=j,两段红色的字符串相等(两个字符串完全相等),s[k....j]==s[m....i]
设s[x...j]=s[j....i] ,记为:(xj=ji)
则可得,以下简写字符串表达方式:
kj=kx+xj;
mi=mj+ji;
因为xj=ji,所以kx=mj,如下图所示
-------------
-------------
k m x j
看到了没,此时又重复上面的模型了,kx=mj,所以可以一直这样递推下去。
所以可以推出一个重要的性质len-next[len]为此字符串的最小循环节。
另外如果len%(len-next[len])==0,此字符串的最小周期就为len/(len-next[i])。
有了这个结论,这题就好做多了。注意判断一下是否原串就是一个重复串。
Time complexity: O(N)
Source code:
/*
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-07-27-21.10
* Time: 0MS
* Memory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define LL long long
#define ULL unsigned long long
using namespace std;
const int MAXN=100010;
char s[MAXN];
int Next[MAXN];
void getNext()
{
Next[0]=0;
int s_len=strlen(s);
for(int i=1,k=0;i<s_len;++i)
{
while(s[i]!=s[k]&&k) k=Next[k-1];
if(s[i]==s[k]) ++k;
Next[i]=k;
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
getNext();
int s_len=strlen(s);
int min_cycle=s_len-Next[s_len-1];
if(min_cycle!=s_len && s_len%min_cycle==0)
{
puts("0");
}
else
{
int need_add=min_cycle-Next[s_len-1]%min_cycle;
printf("%d\n",need_add);
}
}
return 0;
}
/*
*/
模板题 + KMP + 求最小循环节 --- HDU 3746 Cyclic Nacklace
标签:
原文地址:http://www.cnblogs.com/crazyacking/p/4681359.html