https://vjudge.net/contest/278481
可重叠匹配,KMP裸题
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 using namespace std; 5 const int MAXW=1e4+5; 6 const int MAXT=1e6+5; 7 char strW[MAXW],strT[MAXT]; 8 int lenW,lenT; 9 int Next[MAXW]; 10 void GetNext() 11 { 12 int k=Next[0]=-1; 13 int j=0; 14 while(j<lenW) 15 { 16 if(k==-1||strW[k]==strW[j]) Next[++j]=++k; 17 else k=Next[k]; 18 } 19 } 20 int kmp() 21 { 22 int i=0,j=0,ans=0; 23 while(i<lenT) 24 { 25 if(j==-1||strT[i]==strW[j]) ++i,++j; 26 else j=Next[j]; 27 if(j==lenW) 28 { 29 ans++; 30 j=Next[j]; 31 } 32 } 33 return ans; 34 } 35 int read() 36 { 37 int s=1,x=0;char ch=getchar(); 38 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 39 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 40 return s*x; 41 } 42 int main() 43 { 44 int cas=read(); 45 while(cas--) 46 { 47 scanf("%s",strW); 48 scanf("%s",strT); 49 lenW=strlen(strW); 50 lenT=strlen(strT); 51 GetNext(); 52 /*for(int i=1;i<=lenW;++i) 53 cout<<Next[i]<<' ';*/ 54 cout<<kmp()<<endl; 55 } 56 }
KMP裸题
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define ull unsigned long long 4 #define ls(p) (p<<1) 5 #define rs(p) (p<<1|1) 6 using namespace std; 7 const int MAXN=1e6+5; 8 const int MAXM=1e4+5; 9 int n,m; 10 int a[MAXN],b[MAXM]; 11 int Next[MAXM]; 12 void GetNext() 13 { 14 int k=Next[0]=-1; 15 int j=0; 16 while(j<m) 17 { 18 if(k==-1||b[k]==b[j]) Next[++j]=++k; 19 else k=Next[k]; 20 } 21 } 22 int kmp() 23 { 24 int i=0,j=0,ans=-1; 25 while(i<n) 26 { 27 if(j==-1||a[i]==b[j]) ++i,++j; 28 else j=Next[j]; 29 if(j==m) 30 { 31 ans=i-j+1; 32 break; 33 } 34 } 35 return ans; 36 } 37 int read() 38 { 39 int x=0,s=1;char ch=getchar(); 40 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 41 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 42 return x*s; 43 } 44 int main() 45 { 46 int test=read(); 47 while(test--) 48 { 49 n=read();m=read(); 50 for(int i=0;i<n;++i) a[i]=read(); 51 for(int i=0;i<m;++i) b[i]=read(); 52 GetNext(); 53 printf("%d ",kmp()); 54 } 55 return 0; 56 }
如果对于Next数组中的 i,符合 i%(i-Next[i])==0&&Next[i]!=0 则说明字符串循环,而且循环节长度为:i-Next[i] 循环次数为:i/(i-Next[i])
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define lowbit(x) (x&(-x)) 26 using namespace std; 27 const int MAXN=1e6+5; 28 string str; 29 int Next[MAXN],len; 30 void GetNext() 31 { 32 int k=Next[0]=-1; 33 int j=0; 34 while(j<len) 35 { 36 if(k==-1||str[k]==str[j]) Next[++j]=++k; 37 else k=Next[k]; 38 } 39 } 40 int read() 41 { 42 int s=1,x=0; 43 char ch=getchar(); 44 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 45 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 46 return x*s; 47 } 48 int main() 49 { 50 int id=0; 51 ios::sync_with_stdio(false); 52 cin.tie(0);cout.tie(0); 53 while(cin>>len,len) 54 { 55 cout<<"Test case #"<<++id<<" "; 56 cin>>str; 57 GetNext(); 58 for(int i=1;i<=len;++i) 59 { 60 if(Next[i]&&i%(i-Next[i])==0) 61 cout<<i<<' '<<i/(i-Next[i])<<" "; 62 } 63 cout<<endl; 64 } 65 return 0; 66 }
同上,Next数组求最小循环节
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define lowbit(x) (x&(-x)) 26 using namespace std; 27 const int MAXN=1e6+5; 28 string str; 29 int Next[MAXN],len; 30 void GetNext() 31 { 32 int k=Next[0]=-1; 33 int j=0; 34 while(j<len) 35 { 36 if(k==-1||str[k]==str[j]) Next[++j]=++k; 37 else k=Next[k]; 38 } 39 } 40 int read() 41 { 42 int s=1,x=0; 43 char ch=getchar(); 44 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 45 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 46 return x*s; 47 } 48 int main() 49 { 50 ios::sync_with_stdio(false); 51 cin.tie(0);cout.tie(0); 52 while(true) 53 { 54 cin>>str; 55 if(str[0]=='.') return 0; 56 len=str.size(); 57 GetNext(); 58 if(Next[len]==0||len%(len-Next[len])) cout<<1<<endl; 59 else cout<<len/(len-Next[len])<<endl; 60 } 61 return 0; 62 }
求出每个前缀在串中出现的次数之和。
枚举i,对于S[1..i],和前缀S[1..j]相等的可能是后缀S[i-j+1..i],
利用Next数组,Next[i]表示S[1..i]的最长公共前缀后缀,Next[Next[i]]表示S[1..i]的第二长公共前缀后缀...,直到为0
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define lowbit(x) (x&(-x)) 26 using namespace std; 27 const int MAXN=2e5+5; 28 const int MOD=10007; 29 string str; 30 int Next[MAXN],len; 31 void GetNext() 32 { 33 int k=Next[0]=-1; 34 int j=0; 35 while(j<len) 36 { 37 if(k==-1||str[k]==str[j]) Next[++j]=++k; 38 else k=Next[k]; 39 } 40 } 41 int read() 42 { 43 int s=1,x=0; 44 char ch=getchar(); 45 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 46 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 47 return x*s; 48 } 49 void solve() 50 { 51 int ans=0; 52 GetNext(); 53 for(int i=1;i<=len;++i) 54 { 55 int tmp=i; 56 while(tmp) 57 { 58 ans=(ans+1)%MOD; 59 tmp=Next[tmp]; 60 } 61 } 62 cout<<ans<<endl; 63 } 64 int main() 65 { 66 ios::sync_with_stdio(false); 67 cin.tie(0);cout.tie(0); 68 int test;cin>>test; 69 while(test--) 70 { 71 cin>>len>>str; 72 solve(); 73 } 74 return 0; 75 }
最小循环节长度len-Next[len]
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define lowbit(x) (x&(-x)) 26 using namespace std; 27 const int MAXN=1e5+5; 28 string str; 29 int Next[MAXN],len; 30 void GetNext() 31 { 32 int k=Next[0]=-1; 33 int j=0; 34 while(j<len) 35 { 36 if(k==-1||str[k]==str[j]) Next[++j]=++k; 37 else k=Next[k]; 38 } 39 } 40 int read() 41 { 42 int s=1,x=0; 43 char ch=getchar(); 44 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 45 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 46 return x*s; 47 } 48 void solve() 49 { 50 GetNext(); 51 if(Next[len]==0) cout<<len<<endl; 52 else if(len%(len-Next[len])==0) cout<<0<<" ";//已经是循环串 53 else 54 { 55 int T=len-Next[len];//最小循环节长度 56 cout<<(len/T+1)*T-len<<" "; 57 } 58 } 59 int main() 60 { 61 ios::sync_with_stdio(false); 62 cin.tie(0);cout.tie(0); 63 int test;cin>>test; 64 while(test--) 65 { 66 cin>>str; 67 len=str.size(); 68 solve(); 69 } 70 return 0; 71 }
找字符串s1的前缀,字符串s2的后缀,使得它们相同且最长。
令str=s1+s2,求Next数组即可
注意:Next[len]是最长公共前缀后缀,Next[len]-1不一定是第二长的公共前缀后缀,而是Next[Next[len]],下一个是Next[Next[Next[len]]]...
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define lowbit(x) (x&(-x)) 26 using namespace std; 27 const int MAXN=1e5+5; 28 string s1,s2,str; 29 int Next[MAXN],len; 30 void GetNext() 31 { 32 int k=Next[0]=-1; 33 int j=0; 34 while(j<len) 35 { 36 if(k==-1||str[k]==str[j]) Next[++j]=++k; 37 else k=Next[k]; 38 } 39 } 40 int read() 41 { 42 int s=1,x=0; 43 char ch=getchar(); 44 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 45 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 46 return x*s; 47 } 48 int main() 49 { 50 ios::sync_with_stdio(false); 51 cin.tie(0);cout.tie(0); 52 while(cin>>s1>>s2) 53 { 54 str=s1+s2; 55 len=str.size(); 56 GetNext(); 57 if(Next[len]==0) cout<<0<<endl; 58 else 59 { 60 int lens=min(s1.size(),s2.size()),ans=Next[len]; 61 while(ans>lens) 62 { 63 ans=Next[ans]; 64 } 65 cout<<str.substr(0,ans)<<' '<<ans<<endl; 66 } 67 } 68 return 0; 69 }
Hash后求Next数组
https://blog.csdn.net/MaxMercer/article/details/76168361
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define lowbit(x) (x&(-x)) 26 using namespace std; 27 const int MAXN=1e4+5; 28 const int MAXM=80; 29 const int Base=23333; 30 string str[MAXN]; 31 ull row[MAXN],col[MAXM]; 32 int Next_r[MAXM],Next_c[MAXN]; 33 int n,m; 34 int read() 35 { 36 int s=1,x=0; 37 char ch=getchar(); 38 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 39 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 40 return x*s; 41 } 42 void GetNext_r() 43 { 44 int k=Next_r[0]=-1; 45 int j=0; 46 while(j<m) 47 { 48 if(k==-1||col[k]==col[j]) Next_r[++j]=++k; 49 else k=Next_r[k]; 50 } 51 } 52 void GetNext_c() 53 { 54 int k=Next_c[0]=-1; 55 int j=0; 56 while(j<n) 57 { 58 if(k==-1||row[k]==row[j]) Next_c[++j]=++k; 59 else k=Next_c[k]; 60 } 61 } 62 int main() 63 { 64 ios::sync_with_stdio(false); 65 cin.tie(0);cout.tie(0); 66 cin>>n>>m; 67 for(int i=0;i<n;++i) 68 { 69 cin>>str[i]; 70 for(int j=0;j<m;++j) 71 { 72 row[i]=row[i]*Base+str[i][j]; 73 col[j]=col[j]*Base+str[i][j]; 74 } 75 } 76 77 GetNext_r();GetNext_c(); 78 cout<<(m-Next_r[m])*(n-Next_c[n])<<endl; 79 }
Next数组应用
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define lowbit(x) (x&(-x)) 26 using namespace std; 27 const int MAXN=1e6+5; 28 string str; 29 int N,Next[MAXN],len; 30 int read() 31 { 32 int s=1,x=0; 33 char ch=getchar(); 34 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 35 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 36 return x*s; 37 } 38 void GetNext() 39 { 40 int k=Next[0]=-1; 41 int j=0; 42 while(j<len) 43 { 44 if(k==-1||str[j]==str[k]) Next[++j]=++k; 45 else k=Next[k]; 46 } 47 } 48 void solve() 49 { 50 len=str.size(); 51 GetNext(); 52 if(Next[len]==0||len<=2) cout<<0<<endl; 53 else 54 { 55 int t=Next[len]; 56 bool flag=false; 57 while(t&&!flag) 58 { 59 if(3*t>len) 60 { 61 t=Next[t]; 62 continue; 63 } 64 for(int i=t+1;i<=len-t&&!flag;++i) 65 if(Next[i]==t) flag=true; 66 if(!flag) t=Next[t]; 67 } 68 if(flag) cout<<t<<endl; 69 else cout<<0<<endl; 70 } 71 } 72 int main() 73 { 74 ios::sync_with_stdio(false); 75 cin.tie(0);cout.tie(0); 76 cin>>N; 77 while(N--) 78 { 79 cin>>str; 80 solve(); 81 } 82 return 0; 83 }
给定两个串S、T,求串T的每个后缀在串S中出现的次数与长度之积的和。
用Exkmp要方便一点..
https://blog.csdn.net/my_sunshine26/article/details/77991511
再计一点,int最大值*int最大值不会爆long long,但要记得类型转换成long long
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define lowbit(x) (x&(-x)) 26 using namespace std; 27 const int MAXN=1e6+5; 28 const int MOD=1e9+7; 29 string S,T; 30 int lS,lT; 31 int Next[MAXN],Extend[MAXN]; 32 void GetNext() 33 { 34 int a=0,p=0; 35 Next[0]=lT; 36 for(int i=1;i<lT;++i) 37 { 38 if(i>=p||i+Next[i-a]>=p) 39 { 40 if(i>=p) p=i; 41 while(p<lT&&T[p]==T[p-i]) p++; 42 Next[i]=p-i; 43 a=i; 44 } 45 else Next[i]=Next[i-a]; 46 } 47 } 48 void GetExtend() 49 { 50 int a=0,p=0; 51 GetNext(); 52 for(int i=0;i<lS;++i) 53 { 54 if(i>=p||i+Next[i-a]>=p) 55 { 56 if(i>=p) p=i; 57 while(p<lS&&p-i<lT&&S[p]==T[p-i]) p++; 58 Extend[i]=p-i; 59 a=i; 60 } 61 else Extend[i]=Next[i-a]; 62 } 63 } 64 ll sum(int len) 65 { 66 return ((ll)len*((ll)len+1)/2)%MOD; 67 } 68 int main() 69 { 70 ios::sync_with_stdio(false); 71 cin.tie(0);cout.tie(0); 72 int test;cin>>test; 73 while(test--) 74 { 75 cin>>S>>T; 76 lS=S.size(),lT=T.size(); 77 reverse(S.begin(),S.end()); 78 reverse(T.begin(),T.end()); 79 GetExtend(); 80 ll ans=0; 81 for(int i=0;i<lS;++i) 82 { 83 if(Extend[i]) 84 ans=(ans+sum(Extend[i]))%MOD; 85 } 86 cout<<ans<<endl; 87 } 88 }
给定n个串,求最大的i,使得(1<=j<i)且Sj不是Si的子串。
利用子串的传递性,当i是j的子串,j是k的子串时那么i也是k的子串
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 using namespace std; 5 int son[555]; 6 string str[555]; 7 int Next[555][2222]; 8 void GetNext(int it,int len) 9 { 10 int k=Next[it][0]=-1; 11 int j=0; 12 while(j<len) 13 { 14 if(k==-1||str[it][j]==str[it][k]) Next[it][++j]=++k; 15 else k=Next[it][k]; 16 } 17 } 18 bool kmp(int a,int b)//str_a is or not substring of str_b 19 { 20 int m=str[a].size(),n=str[b].size(); 21 int i=0,j=0; 22 while(i<n) 23 { 24 if(j==-1||str[b][i]==str[a][j]) ++i,++j; 25 else j=Next[a][j]; 26 if(j==m) return true; 27 } 28 return false; 29 } 30 void solve(int n) 31 { 32 memset(son,-1,sizeof(son)); 33 for(int i=1;i<=n-1;++i) 34 { 35 GetNext(i,int(str[i].size())); 36 if(kmp(i,i+1)) son[i]=1; 37 else son[i]=0; 38 } 39 int ans=-1; 40 for(int i=n;i>=2&&ans==-1;--i) 41 for(int j=i-1;j>=1&&ans==-1;--j) 42 if(!son[j]&&!kmp(j,i)) ans=i; 43 cout<<ans<<endl; 44 } 45 int main() 46 { 47 ios::sync_with_stdio(false); 48 cin.tie(0);cout.tie(0); 49 int t,n;cin>>t; 50 for(int test=1;test<=t;++test) 51 { 52 cout<<"Case #"<<test<<": "; 53 cin>>n; 54 for(int i=1;i<=n;++i) 55 cin>>str[i]; 56 solve(n); 57 } 58 }
给定n个串求最大公共子串(串长度都为60)
暴力。略
求一个串在令一个串中出现的次数。
KMP模板题
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 using namespace std; 5 const int MAXN=1e6+5; 6 int Next[MAXN]; 7 string S,T; 8 int lS,lT; 9 void GetNext() 10 { 11 int k=Next[0]=-1; 12 int j=0; 13 while(j<lT) 14 { 15 if(k==-1||T[k]==T[j]) Next[++j]=++k; 16 else k=Next[k]; 17 } 18 } 19 int kmp() 20 { 21 GetNext(); 22 int i=0,j=0,res=0; 23 while(i<lS) 24 { 25 if(j==-1||S[i]==T[j]) ++i,++j; 26 else j=Next[j]; 27 if(j==lT) res++,j=Next[j]; 28 } 29 return res; 30 } 31 int main() 32 { 33 ios::sync_with_stdio(false); 34 cin.tie(0);cout.tie(0); 35 int test;cin>>test; 36 for(int t=1;t<=test;++t) 37 { 38 cin>>S>>T; 39 lS=S.size(),lT=T.size(); 40 cout<<"Case "<<t<<": "<<kmp()<<endl; 41 } 42 43 }
在一个串后添加任意字符使得该穿变为回文串,求添加的最少字符
令原串为S,其反串为T,那么S+T一定是个回文串,要长度最小,就是求其重叠长度
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #include<algorithm> 5 using namespace std; 6 const int MAXN=1e6+5; 7 int Next[MAXN]; 8 string S,T; 9 int lS,lT; 10 void GetNext() 11 { 12 int k=Next[0]=-1; 13 int j=0; 14 while(j<lT) 15 { 16 if(k==-1||T[k]==T[j]) Next[++j]=++k; 17 else k=Next[k]; 18 } 19 } 20 int kmp() 21 { 22 GetNext(); 23 int i=0,j=0,res=0; 24 while(i<lS) 25 { 26 if(j==-1||S[i]==T[j]) ++i,++j; 27 else j=Next[j]; 28 } 29 return j; 30 } 31 int main() 32 { 33 ios::sync_with_stdio(false); 34 cin.tie(0);cout.tie(0); 35 int test;cin>>test; 36 for(int t=1;t<=test;++t) 37 { 38 cin>>S; 39 T=S; 40 reverse(T.begin(),T.end()); 41 lS=S.size(),lT=T.size(); 42 cout<<"Case "<<t<<": "<<2*lS-kmp()<<endl; 43 } 44 45 }