POJ2752 Seek the Name, Seek the Fame
本题是求一个fail数组就可以了
但是这一题有一个地方和fail数组定义不同:它自身也算一个最长公共前后缀
这一点想了很久。。。。但是最终发现不用改变fail数组,只需要多输出一个字符串它自己的长度就可以了(因为根据题目定义字符串本身必定是它自己的最长公共前后缀)
由于他要升序,把他丢到一个优先队列就行了
代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<iostream>
#include<queue>
using namespace std;
char s[400010];
int fail[400010];
int len;
void do_fail(){
memset(fail,0,sizeof(fail));
fail[0]=-1;
fail[1]=0;
for (int i=2;i<=len;i++){
int p=fail[i-1];
while ((p!=-1) && (s[p+1]!=s[i])) p=fail[p];
p++;
fail[i]=p;
}
}
int main(){
while (scanf("%s",s+1)!=EOF){
priority_queue <int> q;
len=strlen(s+1);
do_fail();
int p=fail[len];
while (p!=0){
q.push(-p);
p=fail[p];
}
while (!q.empty()){
printf("%d ",-q.top());
q.pop();
}
printf("%d ",len);
printf("\n");
}
}