Description
Input
One line, a string s
Output
A row, an integer that represents the value evaluated
Sample InputCacaoSample Output
54
HINT
2<=n<=500000,s made up of lowercase English letters
YY the solution of the suffix automata:
The first test instructions is to ask for Sigma (LCP (i,j) |i<j)
The string in turn, considering the contribution of the two suffixes to the answer, is actually the oldest string length contained in the LCA node of node X and y
So the SAM structure, consider when the LCA is node Z, how many satisfied conditions (x, y), this enumeration Z of the adjacent sub-node, DP a bit can be
Code:o (n) 2104ms
#include <cstdio>#include<cctype>#include<cstring>#include<algorithm>using namespaceStd;typedefLong LongLL;Const intmaxn=1000010;intn,to[maxn][ -],fa[maxn],l[maxn],f[maxn],x[maxn],w[maxn],od[maxn],cnt=1, last=1;voidExtendintc) { intP,q,np,nq; P=last;last=np=++cnt;l[np]=l[p]+1; f[np]=w[np]=1; for(;! TO[P][C];p =fa[p]) to[p][c]=NP; if(!p) fa[np]=1; Else{Q=To[p][c]; if(l[p]+1==L[Q]) fa[np]=Q; Else{NQ=++cnt;l[nq]=l[p]+1; memcpy (To[nq],to[q],sizeof(To[q])); FA[NQ]=Fa[q]; FA[Q]=fa[np]=NQ; for(; to[p][c]==q;p=fa[p]) to[p][c]=NQ; }}}ll Solve () {LL ans=0; for(intI=1; i<=cnt;i++) x[l[i]]++; for(intI=1; i<=n;i++) x[i]+=x[i-1]; for(intI=1; i<=cnt;i++) od[x[l[i]]--]=i; for(inti=cnt;i;i--) f[fa[od[i]]]+=F[od[i]]; for(intI=1; i<=cnt;i++) {ans+ = (LL) w[fa[i]]*f[i]*L[fa[i]]; W[fa[i]]+=F[i]; } returnans;}CharS[MAXN];intMain () {scanf ("%s", s); N=strlen (s); for(inti=n-1; i>=0; i--) Extend (s[i]-'a'); LL ans=0; for(intI=1; i<=n;i++) ans+= (LL) i* (n1); printf ("%lld\n", ans-2*solve ()); return 0;}
View Code
Also turn the SA solution for Hzwer:
--------------------------------------------------------------------------------------------------------------- -----------------------------the dividing line between Konjac Konjac and God Ben--------------------------------------------
Obviously the suffix array is not the correct posture ...
But let's talk about the suffix array, bzoj, the total time limit is 20s.
SA+RMQ the LCP should be rotten Street, the problem is not RMQ ...
First we find the H array
Consider H[i] in which interval will be the minimum value, this with two times monotonous stack can easily solve
Also deal with the repeated counting problem that may be caused by h[i], see the code
Code O (NLOGN) 13592ms
#include <Set>#include<map>#include<ctime>#include<queue>#include<cmath>#include<cstdio>#include<vector>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#defineN 500005#defineINF 1000000000#definePA pair<int,int>#definell Long Longusing namespacestd;ll ans;intn,k,p,q=1, top;intv[n],a[n],h[n],sa[2][n],rk[2][n];intSt[n],l[n],r[n];CharCh[n];voidMulint*sa,int*rk,int*sa,int*RK) { for(intI=1; i<=n;i++) v[rk[sa[i]]]=i; for(inti=n;i;i--) if(sa[i]>k) Sa[v[rk[sa[i]-k]]--]=sa[i]-K; for(inti=n-k+1; i<=n;i++) sa[v[rk[i]]--]=i; for(intI=1; i<=n;i++) Rk[sa[i]]=rk[sa[i-1]]+ (rk[sa[i-1]]!=rk[sa[i]]| | rk[sa[i-1]+k]!=rk[sa[i]+K]);}voidPresa () { for(intI=1; i<=n;i++) v[a[i]]++; for(intI=1; i<= -; i++) v[i]+=v[i-1]; for(intI=1; i<=n;i++) sa[p][v[a[i]]--]=i; for(intI=1; i<=n;i++) Rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+ (a[sa[p][i-1]]!=A[sa[p][i]]); for(k=1; k<n;k<<=1, Swap (P,Q)) Mul (Sa[p],rk[p],sa[q],rk[q]); for(intk=0, i=1; i<=n;i++) { intj=sa[p][rk[p][i]-1]; while(Ch[j+k]==ch[i+k]) k++; H[rk[p][i]]=k;if(k>0) k--; }}voidsolve () { for(intI=1; i<=n;i++) ans+= (LL) i* (n1); h[0]=-inf; for(intI=1; i<=n;i++) { while(H[i]<=h[st[top]]) top--; if(st[top]==0) l[i]=1; Elsel[i]=st[top]+1; st[++top]=i; } h[n+1]=-inf;top=0; st[0]=n+1; for(inti=n;i;i--) { while(H[i]; if(st[top]==n+1) r[i]=N; Elser[i]=st[top]-1; st[++top]=i; } for(intI=1; i<=n;i++) ans-=2ll* (i-l[i]+1) * (r[i]-i+1)*h[i];}intMain () {scanf ("%s", ch+1); N=strlen (ch+1); for(intI=1; i<=n;i++) a[i]=ch[i]-'a'+1; Presa (); Solve (); printf ("%lld", ans); return 0;}
View Code
BZOJ3238: [Ahoi2013] difference (suffix automaton)