您的位置:首页 > 其它

BZOJ 3238 [Ahoi2013]差异

2016-06-16 17:12 357 查看
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=3238

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

typedef long long ll;
const int maxn=1000010;

int n,last=1,cnt=1;
int a[maxn][26],mx[maxn],fa[maxn];
int T[maxn],Seq[maxn];
int f[maxn],w[maxn];
char ch[maxn];

void extend(int c){
int p=last,np=last=++cnt;
mx[np]=mx[p]+1; f[np]=w[np]=1;
while(!a[p][c] && p) a[p][c]=np,p=fa[p];
if(!p) fa[np]=1;
else{
int q=a[p][c];
if(mx[q]==mx[p]+1) fa[np]=q;
else{
int nq=++cnt;mx[nq]=mx[p]+1;
memcpy(a[nq],a[q],sizeof(a[q]));
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
while(a[p][c]==q) a[p][c]=nq,p=fa[p];
}
}
}

void get_order(){
for(int i=1;i<=cnt;i++) T[mx[i]]++;
for(int i=1;i<=n;i++) T[i]+=T[i-1];
for(int i=1;i<=cnt;i++) Seq[T[mx[i]]--]=i;
}

ll solve(){
ll ans=0;
for(int i=cnt;i>=1;i--) f[fa[Seq[i]]]+=f[Seq[i]];
for(int i=cnt;i>=1;i--){
int x=Seq[i];
ans+=(ll)f[x]*w[fa[x]]*mx[fa[x]];
w[fa[x]]+=f[x];
}
return ans;
}

int main(){
#ifndef ONLINE_JUDGE
freopen("3238.in","r",stdin);
freopen("3238.out","w",stdout);
#endif

scanf("%s",ch);
n=strlen(ch);
for(int i=n-1;i>=0;i--) extend(ch[i]-'a');

ll ans=(ll)(1+n)*n*(n-1)/2;

get_order();
ans-=solve()*2;

printf("%lld",ans);
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: