include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
typedef long long LL;
const int N=200000+10;
char s[N],s1[N];
struct SuffixArray{
int a1[N],a2[N],c[N],SA[N],sa[N],*rank,*x,*y;
int n,height[N],m;
void sort(){
for (int i=0;i<m;i++) c[i]=0;
for (int i=0;i<n;i++) c[x[i]]++;
for (int i=0;i<m;i++) c[i+1]+=c[i];
for (int i=n-1;i>=0;i--) SA[ --c[x[sa[i]]] ] = sa[i];
}
void build_sa(char *s){
n=strlen(s); m=256;
x=a1; y=a2; x[n]=y[n]=-1;
for (int i=0;i<n;i++) x[i]=s[i],sa[i]=i;
sort();
for (int k=1;k<=n;k<<=1){
int p=0;
for (int i=n-k;i<n;i++) sa[p++]=i;
for (int i=0;i<n;i++) if (SA[i]>=k) sa[p++]=SA[i]-k;
sort();
p=0; swap(x,y);
x[SA[0]]=0;
for (int i=1;i<n;i++){
if ( y[ SA[i-1] ]!=y[ SA[i] ] || y[ SA[i-1]+k ]!=y[ SA[i]+k ] ) p++;
x[SA[i]]=p;
}
if (p+1==n) break;
m=p+1;
}
rank=x; getHeight(s);
}
void getHeight(char *s){
int k=0;
for (int i=0;i<n;i++){
if (k) k--;
if (rank[i]==0) continue;
int j=SA[ rank[i]-1 ];
while (i+k<n && j+k<n && s[i+k]==s[j+k]) k++;
height[rank[i]]=k;
}
height[n]=0;
}
}H;
int lc[N*2];
int lx[N],ly[N];
void init(char *s1){
int c=0;
int n=strlen(s1);
s[c++]='$';s[c++]='#';
for (int i=0;s1[i];i++){
s[c++]=s1[i];
s[c++]='#';
}s[c]='\0';
lc[0]=1;lc[1]=1;
int k=1;
for (int i=2;i<c;i++){
int p=k+lc[k]-1;
if (i>=p){
int j=0;
while (i-j>=0 && i+j<c && s[i-j]==s[i+j]) j++;
lc[i]=j; k=i;
}else {
int j=2*k-i;
if (i+lc[j]-1<p) lc[i]=lc[j];
else {
int d=p-i+1;
while (i-d>=0 && i+d<c && s[i-d]==s[i+d]) d++;
lc[i]=d; k=i;
}
}
}
}
void solve(){
int n=strlen(s);
int ret=lc[H.SA[0]];
int tmp=lc[H.SA[0]];
// cout<<s<<endl;
// cout<<H.SA[0]<<" "<<lc[H.SA[0]]<<" "<<s+H.SA[0]<<endl;
for (int i=1;i<n;i++){
int t=H.SA[i];
// cout<<H.SA[i]<<" "<<lc[H.SA[i]]<<" "<<s+H.SA[i]<<endl;
ret+=max(0,(lc[t]-min(H.height[i],tmp))/2);//tmp表示以字符s[H.SA[i-1]]为中心已经被统计过的回文串的个数
if (lc[t]>=tmp) tmp=lc[t];
else {
tmp=min(tmp,H.height[i]);//从上一个传递到当前;
if (lc[t]>tmp) tmp=lc[t];//如果该后缀本身的回文个数更多久更新;
}
}
printf("%d\n",ret-1);
}
int main(){
int T,cas=0;
scanf("%d",&T);
while (T--){
scanf("%s",s1);
init(s1);
H.build_sa(s);
printf("Case #%d: ",++cas);
solve();
}
return 0;
}
tjut 3948
最新推荐文章于 2017-04-12 11:12:14 发布