zoukankan      html  css  js  c++  java
  • 后缀树简短实现

    也没什么好讲的,背下来也没什么问题。

    不过理解更好吧。

    对应洛谷后缀自动机的模板题

    。。。。。。。。。。。。。

    虽然后缀树很强,但是请注意:

    常数还是有的(而且比较大。。。。,估计是唯一不如后缀自动机的地方)

    节点数很难超过1.5*n,考场上可以试试卡卡空间什么的

    #include <cstdio>
    #include <cstring>
    #define sid 2000500
    #define inf 100000000
    #define ri register int
    #define ll long long
    using namespace std;
    
    template <typename re>
    inline void upmax(re &a, re b) { if(a < b) a = b; }
    
    char s[1000050];
    
    struct P {
        int lef, len, link;
        int go[27];
    } t[sid];
    int cnt = 1, act = 1, rem, n;
    ll ans;
    
    int node(int l, int len) {
        t[++ cnt].lef = l; t[cnt].len = len; t[cnt].link = 1;
        return cnt;
    }
    void attend(int i) {
        n ++; s[i] = s[i] - 'a';
        int x = s[i], lst = 1; 
        rem ++;
        while(rem) {
            while(rem > t[t[act].go[s[n - rem + 1]]].len)
                rem -= t[act = t[act].go[s[n - rem + 1]]].len;
            int tar = s[n - rem + 1], &d = t[act].go[tar];
            int c = s[t[d].lef + rem  - 1];
            if(!d || x == c) {
                t[lst].link = act; lst = act;
                if(!d) d = node(n - rem + 1, inf);
                else return;
            }
            else {
                int np = node(t[d].lef, rem - 1);
                t[np].go[x] = node(n, inf); t[np].go[c] = d; 
                t[d].lef += rem - 1; t[d].len -= rem - 1;
                t[lst].link = d = np; lst = d;
            }
            (act == 1) ? rem -- : act = t[act].link;
        }
    }
    
    int has[sid];
    void dfs(int e, int dep) {
        int p = 0;
        if(dep > n) has[e] ++;
        for(int i = 0; i <= 26; i ++) {
            int d = t[e].go[i];
            if(!d) continue;
            dfs(d, dep + t[d].len);
            has[e] += has[d];
        }
        if(has[e] >= 2) upmax(ans, 1ll * has[e] * dep);
    }
    
    int main() {
        scanf("%s", s + 1);
        int n = strlen(s + 1); s[++ n] = 'z' + 1;
        t[0].len = inf;
        for(ri i = 1; i <= n; i ++) attend(s[i]);
        dfs(1, 0);
        printf("%lld
    ", ans);
        return 0;
    }
  • 相关阅读:
    绕口令系列 1
    毕业论文排版
    使用matlab表示“段数不确定”的分段函数
    [转]C/C++关于全局变量和局部变量初始化与不初始化的区别
    [转]基于Protel DXP软件的PCB高级编辑技巧大全
    冒泡排序及其优化
    gcc编译器参数
    [转]跟我一起写Makefile系列
    实例说明optimize table在优化mysql时很重要
    log4php0.9的详细配备实例说明
  • 原文地址:https://www.cnblogs.com/reverymoon/p/8998733.html
Copyright © 2011-2022 走看看