zoukankan      html  css  js  c++  java
  • P4555 [国家集训队]最长双回文串

    题意:求这样一个回文串S,S = A + B 且 A, B都是回文串。问最长S

    题解:建立两颗回文树,一个从前向后插,一个从后向前插,并记录每个位置得到的最长后缀后文。

    ps:马拉车的做法待更

    const int N = 100005;
    
    struct data {
        int len, fail;
        int ch[26];
    };
    
    struct PldTree {
        int tot, last;
        int cnt[N];
    
        char s[N];
        data node[N];
    
        void Inite() {
            tot = last = 1;
            node[0].fail = 1;
            node[1].len = -1;
        }
        void Insert(int i) {
            while(s[i] != s[i - node[last].len - 1]) last = node[last].fail;
            if (!node[last].ch[s[i] - 'a']) {
                node[++tot].len = node[last].len + 2;
                cnt[i] = node[tot].len;
    
                int tp = node[last].fail;
                while(s[i] != s[i - node[tp].len - 1]) tp = node[tp].fail;
    
                node[tot].fail = node[tp].ch[s[i] - 'a'];
                node[last].ch[s[i] - 'a'] = tot;
                last = tot;
            }
            else {
                last = node[last].ch[s[i] - 'a'];
                cnt[i] = node[last].len;
            }
        }
    };
    
    PldTree T1, T2;
    
    inline void upd(int &a, int b) {
        (a < b) && (a = b);
    }
    
    int main()
    {
        T1.Inite();
        T2.Inite();
    
        T1.s[0] = T2.s[0] = '0';
    
        scanf("%s", T1.s + 1);
    
        int n = strlen(T1.s + 1);
        Rep(i, 1, n) {
            T2.s[i] = T1.s[n + 1 - i];
            T1.Insert(i);
        }
    
        Rep(i, 1, n) {
            T2.Insert(i);
        }
    
        int ans = 0;
        Rep(i, 1, n) upd(ans, T1.cnt[i] + T2.cnt[n - i]);
    
        pr(ans);
        return 0;
    }
  • 相关阅读:
    Android中Java反射技术的使用示例
    汉语-词语-念佛:百科
    汉语-词语-纯净:百科
    汉语-词语-具足戒:百科
    汉语-词语-比丘:百科
    汉语-词语-无常:百科
    汉语-词语-脱离:百科
    袁氏-人物-佛学-袁焕仙:百科
    汉语-词语-无量:百科
    汉语-词语-中观:百科
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/9610092.html
Copyright © 2011-2022 走看看