zoukankan      html  css  js  c++  java
  • 回文树板子

    大略:

    回文树本质是一棵树,有两个根,奇根下面都是奇回文,偶根下面是偶回文,偶根(fail)指向奇根,到奇根一定适配。

    1. 求串(S)前缀(0 - i)内本质不同回文串的个数
    2. 求串(S)内每一个本质不同回文串出现的次数
    3. 求串(S)内回文串的个数(其实就是(1)(2)结合起来)
    4. 求以下标i结尾的回文串的个数

    板子:

    struct PAM{
        int nex[maxn][26];  //指向的一个字符的节点
        int fail[maxn]; //失配节点
        int len[maxn];  //当前节点回文长度
        int str[maxn];  //当前添加的字符串
        int cnt[maxn];  //节点出现次数
        int last;	//目前走到哪个节点
        int tot;    //PAM中节点数
        int N;  //添加的串的个数
    
        int newnode(int L){ //新建节点
            for(int i = 0; i < 26; i++) nex[tot][i] = 0;
            len[tot] = L;
            cnt[tot] = 0;
            return tot++;
        }
    
        void init(){
            tot = 0;
            newnode(0);
            newnode(-1);
            last = 0;
            N = 0;
            str[0] = -1;
            fail[0] = 1;	//偶根指向奇根,因为到奇根必匹配
        }
    
        int getfail(int x){ //失配
            while(N - len[x] - 1 < 0 || str[N - len[x] - 1] != str[N]) x = fail[x];
            return x;
        }
    
        void add(char ss){
            int c = ss - 'a';
            str[++N] = c;
            int cur = getfail(last);    //最长可扩增的后缀回文节点
            if(!nex[cur][c]){
                int now = newnode(len[cur] + 2);
                fail[now] = nex[getfail(fail[cur])][c];
                //cur后缀(除自己)的最长的能让now失配的后缀
                nex[cur][c] = now;
            }
            last = nex[cur][c];
            cnt[last]++;
        }
    
        void count(){
            for(int i = tot - 1; i >= 0; i--)   //子节点出现父节点也出现
                cnt[fail[i]] += cnt[i];
        }
    }pam;
    
  • 相关阅读:
    软件工程实践总结-黄紫仪
    beta冲刺总结附(分工)-咸鱼
    beta冲刺总结-咸鱼
    beta冲刺7-咸鱼
    beta冲刺用户测评-咸鱼
    beta冲刺6-咸鱼
    beta冲刺5-咸鱼
    beta冲刺4-咸鱼
    beta冲刺3-咸鱼
    beta冲刺2-咸鱼
  • 原文地址:https://www.cnblogs.com/KirinSB/p/11298491.html
Copyright © 2011-2022 走看看