[BZOJ3238] [AHOI2013] 差异 - 后缀自动机

来源:互联网 发布:微博 知乎 编辑:程序博客网 时间:2024/05/16 10:26

3238: [Ahoi2013]差异

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 1968  Solved: 896
[Submit][Status][Discuss]

Description

Input

一行,一个字符串S

Output

 

一行,一个整数,表示所求值

Sample Input

cacao

Sample Output


54

HINT



2<=N<=500000,S由小写英文字母组成

Source

[Submit][Status][Discuss]

感觉窝会求后缀数组然后完全不会用……

好伐我还是写了SAM2333333。

显然题意只要我们求出∑LCP(i,j)(i!=j)就好

首先我们跑一遍SAM求出后缀树,然后拓扑一下就能求出所有right集合的大小。

显然两个后缀的最长公共前缀长就是他们在后缀树上的lca的深度。

我们可以考虑对每个深度进行分段,即点x对答案的贡献只包含其在后缀树上的父节点的深度以上且在自身深度以下的答案。

显然这样做的答案就是∑deep[i]*∑right[i]-right[son[i]]

又因为right[i]=∑right[son[i]]

那么每个点的贡献就是deep[i]*right[i]*right[i-1]了

#include"bits/stdc++.h"using namespace std;typedef long long ll; const int N=1000005,A=26;struct SAM{    char s[N];int t,l,q[N],last,a[N];    int fail[N],e[N][A],v[N],d[N];    SAM(){t=last=1;}    void extend(int c){        int np=++t,p=last;        d[np]=d[p]+1,v[last=np]=1;        for(;!e[p][c]&&p;p=fail[p])            e[p][c]=np;        if(!p)fail[np]=1;        else {            int q=e[p][c],nq;            if(d[q]!=d[p]+1){                nq=++t;d[nq]=d[p]+1;                memcpy(e[nq],e[q],sizeof(int[A]));                fail[nq]=fail[q];fail[np]=fail[q]=nq;                for(;e[p][c]==q;p=fail[p])e[p][c]=nq;            } else fail[np]=q;        }    }    void read(){scanf("%s",s);l=strlen(s);}    void build(){for(int i=0;i<l;i++)extend(s[i]-'a');}    ll getans(){        for(int i=1;i<=t;i++)a[d[i]]++;        for(int i=1;i<=l;i++)a[i]+=a[i-1];        for(int i=t;i;i--)q[a[d[i]]--]=i;        for(int i=t;i;i--)v[fail[q[i]]]+=v[q[i]];        v[1]=v[0]=0;ll ret=(ll)(l-1)*l*(l+1)/2;        for(int i=2;i<=t;i++)ret-=(ll)v[i]*(v[i]-1)*(d[i]-d[fail[i]]);        return ret;    }} sam; int main(){    sam.read();sam.build();    printf("%lld\n",sam.getans());    return 0; }


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 大人吃退烧药不出汗怎么办 稍微吃点凉水果胃就疼怎么办 1岁宝宝感冒发烧怎么办 3岁小儿反复发烧怎么办 热感冒喉咙疼要怎么办 孩子感冒咳嗽嗓子疼怎么办 孕妇感冒了嗓子疼咳嗽怎么办 4岁宝宝反复高烧怎么办 小孩吃完药不退烧怎么办 六个月婴儿发烧怎么办退烧快点 咳嗽20天老不好怎么办 吃过退烧药出汗怎么办 5岁儿童发烧39度怎么办 小孩烧到39度怎么办 儿童7岁发烧39度怎么办 发烧没药怎么办怎样退烧快 小孩发烧怎么办怎样退烧快 发烧头疼怎么办最快最有效 发烧头晕怎么办最快最有效 婴儿发烧怎么办最快最有效 孩子一直37度8怎么办 一岁半宝宝37度5怎么办 发烧打了针35度怎么办 小孩发烧吃了鱼怎么办 八个月婴儿发烧39度怎么办 婴儿反复发烧39度怎么办 宝宝发烧了怎么办如何退烧 宝宝烧到38.8度怎么办 小孩发烧到39度怎么办 宝贝发烧到40度怎么办 孩子发烧39度8怎么办 儿子发烧39度该怎么办 孩子发烧39度7怎么办 7个月婴儿发烧怎么办 感冒了头发很油怎么办 5岁宝宝发烧39度怎么办 婴儿烧到39.5度怎么办 1岁多宝宝39.5度怎么办 宝宝发烧40多度怎么办 7岁宝宝发烧了怎么办 宝宝反复发烧39度怎么办