zoukankan      html  css  js  c++  java
  • HDU-5421Victor and String

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5421

    因为要在前面插字符,所以维护一个前缀链和后缀链,在同一棵回文树上搞,如果有某个最长回文后缀(或前缀)的长度为总长,那让前缀(或后缀)的last也赋为当前结点。

    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define rep(i,l,r) for (int i=l;i<=r;i++)
    #define down(i,l,r) for (int i=l;i>=r;i--)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define ll long long
    #define maxn 200500
    using namespace std;
    int n,op;
    char c;
    int read(){
        int x=0,f=1; char ch=getchar();
        while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
        while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    struct data{
        ll sum;
        int L,R,tot,fail[maxn],l[maxn],nxt[maxn][30],s[maxn],last[2],cnt[maxn];
        int newnode(int len){
            clr(nxt[tot],0);
            l[tot]=len; cnt[tot]=0;
            return tot++;
        }
        void init(){
            tot=0; sum=0;
            newnode(0); newnode(-1);
            fail[0]=1;
            last[0]=last[1]=1;
            clr(s,-1);
            L=n; R=n-1;
        }
        int getfail(int op,int v){
            if (op) while (s[R-l[v]-1]!=s[R]) v=fail[v];
            else while (s[L+l[v]+1]!=s[L]) v=fail[v];
            return v;
        }
        void add(int op,int c){
            if (op) s[++R]=c; else s[--L]=c;
            int cur=getfail(op,last[op]);
            if (!nxt[cur][c]){
                int now=newnode(l[cur]+2);
                fail[now]=nxt[getfail(op,fail[cur])][c];
                nxt[cur][c]=now;
                cnt[now]=cnt[fail[now]]+1;
            } last[op]=nxt[cur][c];
            if (l[last[op]]==R-L+1) last[op^1]=last[op];
            sum+=cnt[last[op]];
        }
    }T;
    int main(){
     //   freopen("in.txt","r",stdin);
        while (~scanf("%d",&n)){
            T.init();
            rep(i,1,n){
                op=read(); 
                if (op<=2) {
                    c=getchar();
                    T.add(op-1,c-'a');
                }
                else if(op==3) printf("%d
    ",T.tot-2);
                else printf("%lld
    ",T.sum);
            }
        }
        return 0;
    }
  • 相关阅读:
    Linux之C编译器gcc和makefile使用简介
    基于OWin的Web服务器Katana发布版本3
    OAuth和OpenID的区别
    关于 Token,你应该知道的十件事
    HTTP Header 详解
    Entity Framework教程及文章传送门
    CSP(Content Security Policy) 入门教程
    gulp构建工具的几个使用技巧
    浅谈程序员的英语学习
    如何选择正确的angular2学习曲线?
  • 原文地址:https://www.cnblogs.com/ctlchild/p/4991419.html
Copyright © 2011-2022 走看看