Luogu4248 [AHOI2013]差異
阿新 • • 發佈:2020-07-23
https://www.luogu.com.cn/problem/P4248
字尾自動機
觀察原式,類似樹上兩點間距離
顯然,這棵樹是\(Parent\)樹
那麼,跑一遍\(dfs\)即可
\(C++ Code:\)
#include<bits/stdc++.h> #define N 1000005 #define M 1500005 using namespace std; int tot,head[M],d[M],d2[M],nxt[M],sz[M]; int t[N][26],pre[N],len[N]; int n,cnt=1,last=1; long long ans=0; char s[N],s1[N]; void ins(int c) { int p,q; int np=++cnt; sz[np]=1; len[np]=len[last]+1; for (p=last;p&&!t[p][c];p=pre[p]) t[p][c]=np; if (!p) pre[np]=1; else { q=t[p][c]; if (len[p]+1==len[q]) pre[np]=q; else { int g=++cnt; len[g]=len[p]+1; for (int i=0;i<26;i++) t[g][i]=t[q][i]; pre[g]=pre[q]; for (;p&&t[p][c]==q;p=pre[p]) t[p][c]=g; pre[q]=pre[np]=g; } } last=np; } void add(int x,int y,int z) { tot++; d[tot]=y; d2[tot]=z; nxt[tot]=head[x]; head[x]=tot; } void dfs(int u) { for (int i=head[u];i;i=nxt[i]) { int v=d[i]; int v2=d2[i]; dfs(v); ans+=(long long)sz[v]*(n-sz[v])*v2; sz[u]+=sz[v]; } } int main() { scanf("%s",s); n=strlen(s); for (int i=1;i<=n;i++) s1[i-1]=s[n-i]; for (int i=0;i<n;i++) ins(s1[i]-'a'); for (int i=2;i<=cnt;i++) add(pre[i],i,len[i]-len[pre[i]]); dfs(1); cout << ans << endl; return 0; }