• HDU6599 I Love Palindrome String(回文树)


    /*
     * hdu6599
     * 题意:
     * 判断长度从1到len的子串中有多少回文串,且前一半也为回文
     * 题解;
     * 用回文树求出本质不同的回文串,对每个回文串的前一半再判断是否为回文
     */
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef unsigned long long ll;
    const int maxn=3e5+100;
    int a[maxn];
    ll f[maxn];
    ll p[maxn];
    ll cal (int l,int r) {
        if (l==0) return f[r];
        return f[r]-f[l-1]*p[r-l+1];
    }
    bool check (int l,int r) {
        int mid=(l+r)>>1;
        if ((r-l+1)&1)
            return cal(l,mid)==cal(mid,r);
        else
            return cal(l,mid)==cal(mid+1,r);
        //分别判断
    }
    struct palin_Tree {
        //回文树
        int nxt[maxn][26];
        int fail[maxn];
        int len[maxn];
        int cnt[maxn];
        int S[maxn];
        int ind[maxn];
        int last,id,n;
        /*
         * 一个节点一个本质不同的回文串
         * len[i]表示回文串i的长度
         * nxt[i][c]表示编号为i的节点表示的回文串在两边添加字符c以后变成的回文串的编号
         * cnt[i]表示节点i表示的本质不同的串的个数
         * fail[i]表示节点i失配以后跳转不等于自身的节点i表示的回文串的最长后缀回文串
         * last表示新添加一个字母后形成的最长回文串表示的节点
         * S[i]表示第i次添加的字符
         * ind[i]表示第i号节点是插入到第ind[i]号字符串产生的节点
         */
        int newNode (int x) {
            for (int i=0;i<26;i++)
                nxt[id][i]=0;
            cnt[id]=0;
            len[id]=x;
            return id++;
        }
        void init () {
            id=0;
            newNode(0);
            newNode(-1);
            fail[0]=1;
            S[0]=-1;
            last=n=0;
        }
        int getfail (int x) {
            while (S[n-len[x]-1]!=S[n]) x=fail[x];
            return x;
        }
        void insert (int c) {
            c-='a';
            S[++n]=c;
            int cur=getfail(last);
            if (!nxt[cur][c]) {
                int u=newNode(len[cur]+2);
                fail[u]=nxt[getfail(fail[cur])][c];
                nxt[cur][c]=u;
            }
            last=nxt[cur][c];
            cnt[last]++;
            ind[last]=n;
        }
        void getsum () {
            for (int i=id-1;i>=0;i--) cnt[fail[i]]+=cnt[i];
            for (int i=2;i<id;i++)
                if (check(ind[i]-len[i],ind[i]-1))
                    a[len[i]]+=cnt[i];
        }
    }Palin_Tree;
    char s[maxn];
    int main () {
        p[0]=1;
        for (int i=1;i<maxn;i++) p[i]=p[i-1]*13331;
        while (~scanf("%s",s)) {
            int len=strlen(s);
            for (int i=0;i<=len;i++) a[i]=0;
            Palin_Tree.init();
            for (int i=0;i<len;i++) Palin_Tree.insert(s[i]);
            f[0]=s[0];
            for (int i=1;i<len;i++)
                f[i]=f[i-1]*13331+s[i];
            Palin_Tree.getsum();
            for (int i=1;i<=len;i++)
                printf("%d%c",a[i]," 
    "[i==len]);
        }
    }
  • 相关阅读:
    ajax初步(1) fly
    jquery(1) fly
    图片轮播 fly
    仿慕课网教程html+css页面前段时间学习总结(1) fly
    jquery(3)常用方法 fly
    再次遭遇VS设计视图假死
    注册表导致VS2008切换设计视图假死
    BUUCTF PWN 铁人三项(第五赛区)_2018_rop
    buuctf re [FlareOn4]IgniteMe
    buuctf re [WUSTCTF2020]level3
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12841044.html
Copyright © 2020-2023  润新知