zoukankan      html  css  js  c++  java
  • bzoj3238 [Ahoi2013]差异

    Description

    Input

    一行,一个字符串S

    Output 

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

    Sample Input

    cacao

    Sample Output

    54

    HINT

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

    正解:后缀自动机+后缀树。

    这题就是用后缀自动机构造后缀树,然后就很简单了。

    有一个性质,反串的后缀自动机构成的$parent$树就是后缀树。

    然后我们构造出后缀树以后,就可以直接树形$dp$求出答案了。

    另外注意,后缀自动机中新建的结点是不能算进方案中的,因为它并不是后缀结点。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define N (1000010)
     6 
     7 using namespace std;
     8 
     9 struct edge{ int nt,to; }g[N];
    10 
    11 int ch[N][26],head[N],fa[N],sz[N],l[N],la,tot,len,num;
    12 char s[N];
    13 ll ans;
    14 
    15 il int gi(){
    16   RG int x=0,q=1; RG char ch=getchar();
    17   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    18   if (ch=='-') q=-1,ch=getchar();
    19   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    20   return q*x;
    21 }
    22 
    23 il void insert(RG int from,RG int to){
    24   g[++num]=(edge){head[from],to},head[from]=num; return;
    25 }
    26 
    27 il void add(RG int c){
    28   RG int p=la,np=++tot; la=np,l[np]=l[p]+1,sz[np]=1;
    29   for (;p && !ch[p][c];p=fa[p]) ch[p][c]=np;
    30   if (!p){ fa[np]=1; return; } RG int q=ch[p][c];
    31   if (l[q]==l[p]+1) fa[np]=q; else{
    32     RG int nq=++tot; l[nq]=l[p]+1;
    33     fa[nq]=fa[q],fa[q]=fa[np]=nq;
    34     memcpy(ch[nq],ch[q],sizeof(ch[q]));
    35     for (;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
    36   }
    37   return;
    38 }
    39 
    40 il void dfs(RG int x){
    41   for (RG int i=head[x],v;i;i=g[i].nt){
    42     v=g[i].to,dfs(g[i].to);
    43     ans+=1LL*sz[x]*sz[v]*l[x],sz[x]+=sz[v];
    44   }
    45   return;
    46 }
    47 
    48 int main(){
    49 #ifndef ONLINE_JUDGE
    50   freopen("difference.in","r",stdin);
    51   freopen("difference.out","w",stdout);
    52 #endif
    53   scanf("%s",s+1),len=strlen(s+1),tot=la=1;
    54   for (RG int i=len;i;--i) add(s[i]-'a');
    55   for (RG int i=2;i<=tot;++i) insert(fa[i],i);
    56   dfs(1),cout<<1LL*(len-1)*len*(len+1)/2-2*ans; return 0;
    57 }
  • 相关阅读:
    python 多进程-03 进程池
    python 多进程-02 进程间数据共享
    python 多进程-01 基本使用
    python 多线程-02 线程池
    开发者入驻
    小程序组件 scroll-view 下拉加载更多,触底触发事件,容器高度设置
    Array.from在360浏览器和IE浏览器兼容问题
    获取cookie
    背景图左右居中
    uniapp使用uni.setStorageAsync刷新页面数据丢失问题
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7630240.html
Copyright © 2011-2022 走看看