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 }
  • 相关阅读:
    leetcode--Populating Next Right Pointers in Each Node II
    leetcode—Populating Next Right Pointers in Each Node
    Pascal's Triangle II
    leetcode—pascal triangle
    leetcode—triangle
    October 23rd, 2017 Week 43rd Monday
    October 22nd, 2017 Week 43rd Sunday
    October 21st 2017 Week 42nd Saturday
    October 20th 2017 Week 42nd Friday
    October 19th 2017 Week 42nd Thursday
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7630240.html
Copyright © 2011-2022 走看看