zoukankan      html  css  js  c++  java
  • HDU 5421(回文树)

    传送门

    题面:

    Victor loves to play with string. He thinks a string is charming as the string is a palindromic string. 

    Victor wants to play nn times. Each time he will do one of following four operations.

    Operation 1 : add a char cc to the beginning of the string. 

    Operation 2 : add a char cc to the end of the string. 

    Operation 3 : ask the number of different charming substrings. 

    Operation 4 : ask the number of charming substrings, the same substrings which starts in different location has to be counted. 

    At the beginning, Victor has an empty string.

    Input

    The input contains several test cases, at most 55 cases. 

    In each case, the first line has one integer nn means the number of operations. 

    The first number of next nn line is the integer opop, meaning the type of operation. If opop=11 or 22, there will be a lowercase English letters followed. 

    1≤n≤1000001≤n≤100000.

    Output

    For each query operation(operation 3 or 4), print the correct answer.

    Sample Input

    6
    1 a
    1 b
    2 a
    2 c
    3
    4
    8
    1 a
    2 a
    2 a
    1 a
    3
    1 b
    3
    4

    Sample Output

    4
    5
    4
    5
    11

    题意:

        给你n次操作,如果为1,则在字符串后面插入一个字符,如果为2,则在字符串前面插入一个字符,如果为3,则输出当前的字符串中的本质不同的回文串的个数,如果为4,则输出字符串的回文串的个数。

    题目分析:

        拿到这个问题,不难想到一个最简单的算法:用string加前后字符串,并不断建回文树去计算答案。

        但是很显然,这样做的时间复杂度大约在O(n^2)的样子,显然不满足题意。

        因此这个题我们则需要动态地建立回文树。

        考虑到是要在前面插入字符,我们考虑开两个last分别记录两端的端点。

        我们用last[0]表示首部的操作的位置,last[1]表示尾部的操作的位置。

        last[0]的操作即为之前的常规操作,而新的last[1]我们只需要维护当前字串的最长公共前缀,在找fail指针的时候也不断找最长公共前缀即可,剩下的操作跟last[0]即为类似。

        最后需要注意,倘若我们发现当前结点的回文子串的长度是整个字符串,则我们需要将另外一种方向的last指针也指向该结点。(证明另外一种方向也可以从此结点开始拓展)

    代码:

    #include <bits/stdc++.h>
    #define maxn 200005
    using namespace std;
    typedef long long ll;
    struct PAM{
        int next[maxn][26],fail[maxn],S[maxn],num[maxn],len[maxn];
        int id,last[2],n;
        int rb,lb;
        int newnode(int x){
            for(int i=0;i<26;i++) next[id][i]=0;
            len[id]=x;
            num[id]=0;
            return id++;
        }
        void init(int x){
            id=0;
            newnode(0);
            newnode(-1);
            memset(S,-1,sizeof(S));
            lb=x,rb=x-1;
            last[0]=last[1]=n=0;
            fail[0]=1;
        }
        int getfail(int x,int d){
            if(d==0) while(S[lb+len[x]+1]!=S[lb]) x=fail[x];
            else while(S[rb-len[x]-1]!=S[rb]) x=fail[x];
            return x;
        }
        int Insert(int c,int d){
            if(d==0) S[--lb]=c;
            else S[++rb]=c;
            int cur=getfail(last[d],d);
            if(!next[cur][c]){
                int now=newnode(len[cur]+2);
                fail[now]=next[getfail(fail[cur],d)][c];
                num[now]=num[fail[now]]+1;
                next[cur][c]=now;
            }
            last[d]=next[cur][c];
            if(len[last[d]]==rb-lb+1) last[d^1]=last[d];//将另一种情况的last也指向该结点
            return num[last[d]];
        }
    }pam;
    int main()
    {
        int n;
        while(~scanf("%d",&n)){
            ll ans=0;
            pam.init(n);
            for(int i=0;i<n;i++){
                int op;
                char ch;
                scanf("%d",&op);
                if(op==1){
                    scanf(" %c",&ch);
                    ans+=pam.Insert(ch-'a',0);
                }
                else if(op==2){
                    scanf(" %c",&ch);
                    ans+=pam.Insert(ch-'a',1);
                }
                else if(op==3){
                    printf("%d
    ",pam.id-2);
                }
                else{
                    cout<<ans<<endl;
                }
            }
        }
    
    }
    
  • 相关阅读:
    springAOP源码分析之篇三:代理对象的执行
    springAOP源码分析之篇二:代理对象的生成
    css样式float造成的浮动“塌陷”问题的解决办法
    css font的简写规则
    CSS学习
    工具
    用过的库
    The requested URL ***** was not found on this serve
    修改DeDe标签Pagelist分页样式
    DedeCms autoindex和itemindex使用介绍
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007206.html
Copyright © 2011-2022 走看看