For each prefix with length P of a given string S,if
S[i]=S[i+P] for i in [0..SIZE(S)-p-1],
then the prefix is a “period” of S. We want to all the periodic prefixs.
Input
Input contains multiple cases.
The first line contains an integer T representing the number of cases. Then following T cases.
Each test case contains a string S (1 <= SIZE(S) <= 1000000),represents the title.S consists of lowercase ,uppercase letter.
Output
For each test case, first output one line containing "Case #x: y", where x is the case number (starting from 1) and y is the number of periodic prefixs.Then output the lengths of the periodic prefixs in ascending order.
Sample Input
4 ooo acmacmacmacmacma fzufzufzuf stostootssto
Sample Output
Case #1: 3 1 2 3 Case #2: 6 3 6 9 12 15 16 Case #3: 4 3 6 9 10 Case #4: 2 9 12题意:找前缀后缀相同的地方题解:kmp 的next数组(我居然没想到@。@)想成最小环了。。。
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 1000000007 using namespace std; const int N=1000000+5,maxn=1000000+5,inf=1e9+5; int Next[N],slen,plen; string str,ptr; void getnext() { Next[0]=-1; int k=-1; for(int i=1;i<slen;i++) { while(k>-1&&str[k+1]!=str[i])k=Next[k]; if(str[k+1]==str[i])k++; Next[i]=k; } } bool kmp() { int k=-1; for(int i=0;i<plen;i++) { while(k>-1&&str[k+1]!=ptr[i])k=Next[k]; if(str[k+1]==ptr[i])k++; if(k==slen-1)return 1; } return 0; } int main() { ios::sync_with_stdio(false); cin.tie(0); int t,n,cnt=0; cin>>t; while(t--){ cin>>str; slen=str.size(); getnext(); for(int i=0;i<slen;i++) cout<<Next[i]<<" "; cout<<endl; vector<int>q; int k=Next[slen-1],loop=slen-Next[slen-1]-1; while(k!=-1){ q.push_back(slen-1-k); k=Next[k]; } q.push_back(slen); /* cout<<"Case #"<<++cnt<<": "<<q.size()<<endl; for(int i=0;i<q.size();i++) cout<<q[i]<<(i==q.size()-1 ? "\n":" ");*/ } return 0; }
时间: 2024-11-18 06:23:26