zoukankan      html  css  js  c++  java
  • hihocoder 后缀自动机二·重复旋律5

    求不同子串个数

    裸的后缀自动机

     1 #include<cstring>
     2 #include<cmath>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cstdio>
     6 
     7 #define ll long long
     8 #define N 2000007
     9 using namespace std;
    10 inline int read()
    11 {
    12     int x=0,f=1;char ch=getchar();
    13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    14     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 
    18 int n;
    19 ll ans;
    20 struct sam
    21 {
    22     int last,cnt;
    23     int c[N][26],fa[N],mx[N];
    24     sam(){last=cnt=1;}
    25     void extend(int x)
    26     {
    27         int p=last,np=last=++cnt;mx[np]=mx[p]+1;
    28         while(p&&!c[p][x])
    29         {
    30             c[p][x]=np;
    31             p=fa[p];
    32         }
    33         if(!p)fa[np]=1;
    34         else
    35         {
    36             int q=c[p][x];
    37             if(mx[q]==mx[p]+1)fa[np]=q;
    38             else
    39             {
    40                 int nq=++cnt;mx[nq]=mx[p]+1;
    41                 memcpy(c[nq],c[q],sizeof(c[q]));
    42                 fa[nq]=fa[q];
    43                 fa[q]=fa[np]=nq;
    44                 while(c[p][x]==q)c[p][x]=nq,p=fa[p];
    45             }
    46         }
    47     }
    48 }sam;
    49 char s[N];
    50 
    51 int main()
    52 {
    53     scanf("%s",s+1);n=strlen(s+1);
    54     for (int i=1;i<=n;i++)
    55         sam.extend(s[i]-'a');
    56     for (int i=1;i<=sam.cnt;i++)
    57         ans+=sam.mx[i]-sam.mx[sam.fa[i]];
    58     printf("%lld",ans);
    59 }
  • 相关阅读:
    2019第二周作业
    2019 编程总结
    寒假作业2编程总结
    2018秋季学习总结
    喜欢的老师
    人生路上对我影响最大的三位老师
    自我介绍
    抓老鼠啊~亏了还是赚了?
    币值转换
    打印沙漏
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8503921.html
Copyright © 2011-2022 走看看