zoukankan      html  css  js  c++  java
  • 后缀自动机三·重复旋律6

    后缀自动机三·重复旋律6

     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 green[maxn<<1], ind[maxn<<1], cnt[maxn<<1];
     7 int ans[maxn];
     8 int sz;
     9 
    10 int news(int maxl, int minl, int *trans, int lk){
    11     maxlen[sz] = maxl;
    12     minlen[sz] = minl;
    13     green[sz] = 0;
    14     cnt[sz] = 0;
    15     ind[sz] = 0;
    16     for(int i = 0; i < 26; i++){
    17         if(trans == NULL) tr[sz][i] = -1;
    18         else tr[sz][i] = trans[i];
    19     }
    20     link[sz] = lk;
    21     return sz++;
    22 }
    23 int add(char ch, int u){
    24     int c = ch - 'a';
    25     int z = news(maxlen[u] + 1, -1, NULL, -1);
    26     green[z] = 1;
    27     int v = u;
    28     while(~v && tr[v][c] == -1){
    29         tr[v][c] = z;
    30         v = link[v];
    31     }
    32     if(v == -1){
    33         minlen[z] = 1;
    34         link[z] = 0;
    35         ind[0]++;
    36         return z;
    37     }
    38     int x = tr[v][c];
    39     if(maxlen[v] + 1 == maxlen[x]){
    40         minlen[z] = maxlen[x] + 1;
    41         link[z] = x;
    42         ind[x]++;
    43         return z;
    44     }
    45     int y = news(maxlen[v] + 1, -1, tr[x], link[x]);
    46     minlen[x] = maxlen[y] + 1;
    47     link[x] = y;
    48     minlen[z] = maxlen[y] + 1;
    49     link[z] = y;
    50     ind[y] += 2;
    51     int w = v;
    52     while(~w && tr[w][c] == x){
    53         tr[w][c] = y;
    54         w = link[w];
    55     }
    56     minlen[y] = maxlen[link[y]] + 1;
    57     return z;
    58 }
    59 void top(){
    60     queue<int> q;
    61     for(int i = 0; i < sz; i++) if(!ind[i]) q.push(i);
    62     while(!q.empty()){
    63         int u = q.front();
    64         q.pop();
    65         if(green[u]) cnt[u]++;
    66         cnt[link[u]] += cnt[u];
    67         if(!(--ind[link[u]])) q.push(link[u]);
    68     }
    69 }
    70 int main(){
    71     while(scanf("%s", s) != EOF){
    72         int len = strlen(s);
    73         sz = 0;
    74         int pre = news(0, 0, NULL, -1);
    75         for(int i = 0; i < len; i++){
    76             pre = add(s[i], pre);
    77         }
    78         top();
    79         for(int i = 0; i < sz; i++) ans[maxlen[i]] = max(ans[maxlen[i]], cnt[i]);
    80         for(int i = len - 1; i > 0; i--) ans[i] = max(ans[i], ans[i + 1]);
    81         for(int i = 1; i <= len; i++) printf("%d
    ", ans[i]);
    82     }
    83 }
    View Code
  • 相关阅读:
    OC学习 Extension
    OC习题 切分字符串 处理色值和名称 (知识点: 字典,枚举,数组,字符串)
    OC学习 Protocol delegate
    epoll反应堆模型
    socket IPC(本地套接字 domain)
    UDP协议简单的CS模型实现
    linux系统编程统计一个目录下的普通文件个数
    Vs2003多窗口下的复杂数据传递
    NET下XML的访问
    OWC中双刻度图表的实现
  • 原文地址:https://www.cnblogs.com/yijiull/p/8506372.html
Copyright © 2011-2022 走看看