1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
#include<bits/stdc++.h> using namespace std;
using ll=long long;
constexpr int N=2e6+5; int _=1;
int n; ll ans; struct SA{ int n,m; char s[N]; int sa[N],rk[N],height[N],h[N]; int minn[21][N],lg[N]; void init(int _n,int _m){ n=_n; m=_m; } void buildsa(){ static int oldrk[N<<1],id[N],px[N],cnt[N]; int i,p,w; for(i=1;i<=m+1;i++) cnt[i]=0; for(i=1;i<=n+1;++i) sa[i]=rk[i]=id[i]=px[i]=0; for(i=1;i<=n*2;i++) oldrk[i]=0; for(i=1;i<=n;++i) ++cnt[rk[i]=(s[i]-'a'+1)]; for(i=1;i<=m;++i) cnt[i]+=cnt[i-1]; for(i=n;i>=1;--i) sa[cnt[rk[i]]--]=i; for(w=1;;w<<=1,m=p){ for(p=0,i=n;i>n-w;--i) id[++p]=i; for(i=1;i<=n;++i) if(sa[i]>w) id[++p]=sa[i]-w; for(i=1;i<=m;i++) cnt[i]=0; for(i=1;i<=n;++i) ++cnt[px[i]=rk[id[i]]]; for(i=1;i<=m;++i) cnt[i]+=cnt[i-1]; for(i=n;i>=1;--i) sa[cnt[px[i]]--]=id[i]; for(i=1;i<=n;i++) oldrk[i]=rk[i]; for(p=0,i=1;i<=n;++i) rk[sa[i]]=(oldrk[sa[i]]==oldrk[sa[i-1]]&&oldrk[sa[i]+w]==oldrk[sa[i-1]+w])?p:++p; if(p==n){ for(i=1;i<=n;++i) sa[rk[i]]=i; break; } } } void buildheight(){ for(int i=1;i<=n+1;++i) height[i]=h[i]=0; int k=0; for(int i=1;i<=n;i++){ if(rk[i]==1) continue; if(k) --k; int j=sa[rk[i]-1]; while(j+k<=n&&i+k<=n&&s[i+k]==s[j+k]) k++; height[rk[i]]=k; } for(int i=1;i<=n;i++) h[i]=height[rk[i]]; for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1; for(int i=1;i<=n;i++) minn[0][i]=height[i]; for(int j=1;(1<<j)<=n;j++) for(int i=1;i+(1<<j)-1<=n;i++) minn[j][i]=min(minn[j-1][i],minn[j-1][i+(1<<(j-1))]); } int get_lcp(int l,int r){ if(l==r) return n-l+1; l=rk[l],r=rk[r]; if(l>r) swap(l,r); l++; int k=lg[r-l+1]; return min(minn[k][l],minn[k][r-(1<<k)+1]); } }sa;
int get_lcp(int x,int y){ if(x<1||x>n||y<1||y>n) return 0; return sa.get_lcp(x,y); }
int get_lcs(int x,int y){ if(x<1||x>n||y<1||y>n) return 0; x=n-x+1+n+1; y=n-y+1+n+1; return sa.get_lcp(x,y); }
ll calc(int len){ ll res=1ll*len*(n-len+1); for(int i=len;i+len<=n;i+=len){ int x=min(get_lcs(i,i+len),len); int y=get_lcp(i+1,i+1+len); ll cnt=1ll*x*(y/len); y%=len; cnt+=max(0,y-(len-x)+1); res+=cnt*len; } return res; }
void work(){ ans=0; cin>>sa.s+1; n=strlen(sa.s+1); sa.s[n+1]=('z'+1); for(int i=1;i<=n;i++) sa.s[i+n+1]=sa.s[n-i+1]; sa.init(n*2+1,27); sa.buildsa(); sa.buildheight(); for(int i=1;i<=n;i++) ans+=calc(i); cout<<ans<<"\n"; }
int main(){ ios::sync_with_stdio(0); cin.tie(0);cout.tie(0);
cin>>_; while(_--){ work(); }
return true&&false; }
|