[AHOI2013] 差异
Description
求 \(\sum {len(T_i) + len(T_j) - 2 lcp(T_i,T_j)}\) 的值
其中 \(T_i (i = 1,2,...,n)\) 为后缀串 \(S[i,n]\)
Solution
单调栈乱扫一发即可。
始终维护当前栈内元素的和,然后加进答案里。
#include <bits/stdc++.h> using namespace std; #define int long long int n,m=256,sa[1000005],y[1000005],u[1000005],v[1000005],o[1000005],r[1000005],h[1000005],T; char str[1000005]; int ans = 0, sum = 0; int sta[1000005],stap[1000005],top=0; signed main(){ cin>>str+1; n=strlen(str+1); for(int i=1;i<=n;i++) u[str[i]]++; for(int i=1;i<=m;i++) u[i]+=u[i-1]; for(int i=n;i>=1;i--) sa[u[str[i]]--]=i; r[sa[1]]=1; for(int i=2;i<=n;i++) r[sa[i]]=r[sa[i-1]]+(str[sa[i]]!=str[sa[i-1]]); for(int l=1;r[sa[n]]<n;l<<=1) { memset(u,0,sizeof u); memset(v,0,sizeof v); memcpy(o,r,sizeof r); for(int i=1;i<=n;i++) u[r[i]]++, v[r[i+l]]++; for(int i=1;i<=n;i++) u[i]+=u[i-1], v[i]+=v[i-1]; for(int i=n;i>=1;i--) y[v[r[i+l]]--]=i; for(int i=n;i>=1;i--) sa[u[r[y[i]]]--]=y[i]; r[sa[1]]=1; for(int i=2;i<=n;i++) r[sa[i]]=r[sa[i-1]]+((o[sa[i]]!=o[sa[i-1]])||(o[sa[i]+l]!=o[sa[i-1]+l])); } { int i,j,k=0; for(int i=1;i<=n;h[r[i++]]=k) for(k?k--:0,j=sa[r[i]-1];str[i+k]==str[j+k];k++); } for(int i=1;i<=n;i++) { ans += i*(n-1ll); } for(int i=1;i<=n;i++) { while(top && sta[top]>=h[i]) { sum -= sta[top] * (stap[top]-stap[top-1]); --top; } ++top; sta[top]=h[i]; stap[top]=i; sum += sta[top] * (stap[top]-stap[top-1]); //cout<<"i="<<i<<" sum="<<sum<<endl; ans -= 2ll*sum; } cout<<ans<<endl; }