您的位置:首页 > 其它

BZOJ——T 1355: [Baltic2009]Radio Transmission

2017-08-14 17:23 253 查看

http://www.lydsy.com/JudgeOnline/problem.php?id=1355

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 964  Solved: 664
[Submit][Status][Discuss]

Description

给你一个字符串,它是由某个字符串不断自我连接形成的。 但是这个字符串是不确定的,现在只想知道它的最短长度是多少.

Input

第一行给出字符串的长度,1 < L ≤ 1,000,000. 第二行给出一个字符串,全由小写字母组成.

Output

输出最短的长度

Sample Input

8
cabcabca

Sample Output

3

HINT

对于样例,我们可以利用"abc"不断自我连接得到"abcabcabc",读入的cabcabca,是它的子串

Source

 

求出A串在KMP算法中A的next数组 设A的长度为N 则答案为A的前N-next

为什么? 分两种情况讨论: next
> N/2 next
<= N/2

画个图比划比划~~

#include <algorithm>
#include <cstdio>

using namespace std;

const int N(1000000+5);
int n,next
;
char s
;

inline void Get_next()
{
int j=0;
for(int i=2;i<=n;i++)
{
for(;j>0&&s[i]!=s[j+1];) j=next[j];
if(s[i]==s[j+1]) j++;
next[i]=j;
}
}

int main()
{
scanf("%d%s",&n,s+1);
Get_next();
printf("%d",n-next
);
return 0;
}

 

枚举循环节长度L 用哈希判断A[1…L],A[L+1…2L],A[2L+1…3L]……是否相等 最后一个循环节长度可能不足L,特殊判断

但我T了、、、

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

#define ull unsigned long long
#define p 233
const int N(1000000+5);
ull n,hash
;
char s
;

inline void Get_hash()
{
for(int i=1;i<=strlen(s+1);i++)
hash[i]=hash[i-1]*p+s[i]-'a';
}
inline ull Check(ull x,ull y,ull P)
{
return hash[y]-hash[x-1]*P;
}

int main()
{
scanf("%d%s",&n,s+1);
Get_hash();
ull P=p;
for(int L=1;L<=n;L++,P*=p)
{
bool flag=1;
for(int i=L+1;i<=n/L*L;i+=L)
if(Check(i,i+L-1,P)!=hash[L])
{
flag=0;
break;
}
if(!flag) continue;
for(int i=n/L*L+1;i<=n;i++)
if(s[i]!=s[i-n/L*L])
{
flag=0;
break;
}
if(!flag) continue;
printf("%d",L);
break;
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: