tjut 3948

来源:互联网 发布:iphone主题软件下载 编辑:程序博客网 时间:2024/06/15 13:53
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;}

0 0
原创粉丝点击