• 后缀自动机二·重复旋律5


    后缀自动机二·重复旋律5

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 1000010;
     4 char s[maxn];
     5 int maxlen[maxn<<1], minlen[maxn<<1], tr[maxn<<1][26], link[maxn<<1];
     6 int sz;
     7 
     8 int news(int maxl, int minl, int *trans, int lk){
     9     maxlen[sz] = maxl;
    10     minlen[sz] = minl;
    11     for(int i = 0; i < 26; i++){
    12         if(trans == NULL) tr[sz][i] = -1;
    13         else tr[sz][i] = trans[i];
    14     }
    15     link[sz] = lk;
    16     return sz++;
    17 }
    18 int add(char ch, int u){
    19     int c = ch - 'a';
    20     int z = news(maxlen[u] + 1, -1, NULL, -1);
    21     int v = u;
    22     while(~v && tr[v][c] == -1){
    23         tr[v][c] = z;
    24         v = link[v];
    25     }
    26     if(v == -1){
    27         minlen[z] = 1;
    28         link[z] = 0;
    29         return z;
    30     }
    31     int x = tr[v][c];
    32     if(maxlen[v] + 1 == maxlen[x]){
    33         minlen[z] = maxlen[x] + 1;
    34         link[z] = x;
    35         return z;
    36     }
    37     int y = news(maxlen[v] + 1, -1, tr[x], link[x]);
    38     minlen[x] = maxlen[y] + 1;
    39     link[x] = y;
    40     minlen[z] = maxlen[y] + 1;
    41     link[z] = y;
    42     int w = v;
    43     while(~w && tr[w][c] == x){
    44         tr[w][c] = y;
    45         w = link[w];
    46     }
    47     minlen[y] = maxlen[link[y]] + 1;
    48     return z;
    49 }
    50 
    51 int main(){
    52     while(scanf("%s", s) != EOF){
    53         int len = strlen(s);
    54         sz = 0;
    55         int pre = news(0, 0, NULL, -1);
    56         for(int i = 0; i < len; i++){
    57             pre = add(s[i], pre);
    58         }
    59         long long ans = 0;
    60         for(int i = 1; i < sz; i++) ans += maxlen[i] - minlen[i] + 1;
    61         printf("%lld
    ", ans);
    62     }
    63 }
    1
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 1000010;
     4 int len[maxn<<1], tr[maxn<<1][26], link[maxn<<1];
     5 int sz, last;
     6 long long ans;
     7 void init(){
     8     sz = last = 0;
     9     len[0] = 0, link[0] = -1;
    10     memset(tr, -1, sizeof tr);
    11     ++sz;
    12 }
    13 void sa(int c){
    14     c = c - 'a';
    15     int cur = sz++;
    16     len[cur] = len[last] + 1;
    17     int p;
    18     for(p = last; ~p && tr[p][c] == -1; p = link[p]){
    19         tr[p][c] = cur;
    20     }
    21     if(p == -1) link[cur] = 0;
    22     else{
    23         int q = tr[p][c];
    24         if(len[p] + 1 == len[q]) link[cur] = q;
    25         else{
    26             int co = sz++;
    27             len[co] = len[p] + 1;
    28             for(int i = 0; i < 26; i++) tr[co][i] = tr[q][i];
    29             link[co] = link[q];
    30             for(; ~p && tr[p][c] == q; p = link[p]) tr[p][c] = co;
    31             link[q] = link[cur] = co;
    32         }
    33     }
    34     last = cur;
    35     ans += len[cur] - len[link[cur]];
    36 }
    37 char s[maxn];
    38 //long long solve(int u){
    39 //    if(u == -1) return 0;
    40 //    long long temp = 0;
    41 //    for(int i = 0; i < 26; i++){
    42 //        temp += solve(tr[u][i]);
    43 //    }
    44 //    return temp + 1;
    45 //}
    46 int main(){
    47     while(scanf("%s", s) != EOF){
    48         init();
    49         ans = 0;
    50         int len = strlen(s);
    51         for(int i = 0; i < len; i++) sa(s[i]);
    52         //ans = solve(0);
    53         printf("%lld
    ", ans);
    54     }
    55 }
    2
  • 相关阅读:
    shell 测试命令
    shell 键盘录入和运算
    shell 的变量
    shell 脚本 helloworld
    让windows系统的DOS窗口也可以显示utf8字符集
    wxpython发布还自己图标的程序
    弥补wxpython无背景图片缺陷
    wxPython实现在浏览器中打开链接
    使用py2exe发布windows平台Python
    python os模块实用函数
  • 原文地址:https://www.cnblogs.com/yijiull/p/8506368.html
Copyright © 2020-2023  润新知