将串反过来 后缀数组 然后用set维护一个序列 插入时修改答案即可
#include<cstdio> #include<cstdlib> #include<algorithm> #include<set> using namespace std; typedef long long ll; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } const int N=100005; int sx[N],icnt; inline int Bin(int x) { return lower_bound(sx+1,sx+icnt+1,x)-sx; } int n,a[N]; int sa[N],t1[N],t2[N],c[N]; int height[N],rank[N]; inline void SA(int *r,int m) { int *x=t1,*y=t2; for (int i=0;i<=m;i++) c[i]=0; for (int i=1;i<=n;i++) c[x[i]=r[i]]++; for (int i=1;i<=m;i++) c[i]+=c[i-1]; for (int i=n;i;i--) sa[c[x[i]]--]=i; for (int k=1;k<=n;k<<=1) { int p=0; for (int i=n-k+1;i<=n;i++) y[++p]=i; for (int i=1;i<=n;i++) if (sa[i]>k) y[++p]=sa[i]-k; for (int i=0;i<=m;i++) c[i]=0; for (int i=1;i<=n;i++) c[x[y[i]]]++; for (int i=1;i<=m;i++) c[i]+=c[i-1]; for (int i=n;i;i--) sa[c[x[y[i]]]--]=y[i]; swap(x,y); x[sa[1]]=1; p=1; for (int i=2;i<=n;i++) x[sa[i]]=(y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])?p:++p; if (p>=n) break; m=p; } } inline void GetHeight(int *S,int *sa,int n) { int j,k=0; for (int i=1;i<=n;i++) rank[sa[i]]=i; for (int i=1;i<=n;height[rank[i++]]=k) for (k?k--:0,j=sa[rank[i]-1];S[i+k]==S[j+k];) k++; } namespace ST{ int st[N][20],Log[N]; inline void Build(int n,int *a){ for (int i=2;i<=n;i++) Log[i]=Log[i>>1]+1; for (int i=1;i<=n;i++) st[i][0]=a[i]; for (int k=1;k<20;k++) for (int i=1;i<=n;i++) { st[i][k]=st[i][k-1]; if (i+(1<<(k-1))<=n) st[i][k]=min(st[i][k],st[i+(1<<(k-1))][k-1]); } } inline int Query(int l,int r){ int t=Log[r-l+1]; return min(st[l][t],st[r-(1<<t)+1][t]); } } set<int> Set; typedef set<int>::iterator ITER; int pre[N],nxt[N]; ll ans,cnt[N]; inline int Height(int x,int y){ return ST::Query(x+1,y); } int main() { int p,now; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); for (int i=1;i<=n;i++) read(a[i]),sx[++icnt]=a[i]; reverse(a+1,a+n+1); sort(sx+1,sx+icnt+1); icnt=unique(sx+1,sx+icnt+1)-sx-1; for (int i=1;i<=n;i++) a[i]=Bin(a[i]); SA(a,icnt); GetHeight(a,sa,n); ST::Build(n,height); Set.insert(0); for (int i=n;i;i--) { now=rank[i]; ITER it=Set.upper_bound(now); if (it!=Set.end()) { p=*it; ans-=cnt[p]; cnt[p]=(n-sa[p]+1)-Height(now,p); ans+=cnt[p]; } p=*(--it); cnt[now]=(n-i+1)-Height(p,now); Set.insert(now);; ans+=cnt[now]; printf("%lld\n",ans); } return 0; }