• HDU-5421 Victor and String 回文自动机


    HDU-5421 Victor and String

    题意

    给定一个空串(S),有(n)次操作,操作有如下四种:

    • (1~c),在(S)前增加一个字符(c)
    • (2~c),在(S)后增加一个字符(c)
    • (3),输出(S)中本质不同的回文子串个数。
    • (4),输出(S)中不同的回文子串个数,位置不同的子串算多个。

    (nle 10^5)

    分析

    回文自动机额外记录一个前端插入的last即可,前端插入和后端插入操作是类似的,唯一和之前不同的地方是当(last)是整个串时,要更新另外一端的(last)为当前这一端的(last)

    Code

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,mid,p<<1
    #define rson mid+1,r,p<<1|1
    #define ll long long
    using namespace std;
    const int inf=1e9;
    const int mod=1e9+7;
    const int maxn=5e5+10;
    char s[maxn];
    int n,now,l,r;
    ll ans;
    struct PAM{
        int son[maxn][26],fail[maxn],len[maxn],cnt[maxn],tot,suf,pre,last;
        int newnode(int x){
            ++tot;
            for(int i=0;i<26;i++) son[tot][i]=0;
           	fail[tot]=0;len[tot]=x;
            return tot;
        }
        void init(){
            tot=-1;newnode(0);newnode(-1);
            fail[0]=1;
            suf=pre=0;
            l=1e5+5,r=l-1;
        }
        int gao(int x,int op){
            while(s[now+op*len[x]+op]!=s[now]) x=fail[x];
            return x;
        }
        void insert(int op){
        	int last=op==1?pre:suf;
            int p=gao(last,op);
            if(!son[p][s[now]-'a']){
                int tmp=son[gao(fail[p],op)][s[now]-'a'];
                son[p][s[now]-'a']=newnode(len[p]+2);
                fail[tot]=tmp;
                cnt[tot]=cnt[tmp]+1;
            }
            last=son[p][s[now]-'a'];
            ans+=cnt[last];
            if(op==1) pre=last;
            else suf=last;
            if(len[last]==r-l+1) suf=pre=last;
        }
        int qy(){
            return len[last];
        }
    }P;
    int main(){
    	while(~scanf("%d",&n)){
    		memset(s,0,sizeof(s));
    	    P.init();
    	    ans=0;
    	    while(n--){
    	    	int op;
    	    	char c;
    	    	scanf("%d",&op);
    	    	if(op==1){
                    scanf(" %c",&c);
    	    		s[--l]=c;
    	    		now=l;
    	    		P.insert(1);
    	    	}else if(op==2){
    	    		scanf(" %c",&c);
    	    		s[++r]=c;
    	    		now=r;
    	    		P.insert(-1);
    	    	}else if(op==3){
    	    		printf("%d
    ",P.tot-1);
    	    	}else{
    	    		printf("%lld
    ",ans);
    	    	}
    	    }
    	}
        return 0;
    }
    
  • 相关阅读:
    qml 无边框
    Qt 参考链接
    QPushButton QSS
    Head First设计模式之备忘录模式
    Head First设计模式之访问者模式
    Head First设计模式之状态模式
    web打印总结
    Head First设计模式之单例模式
    .Net IOC框架入门之一 Unity
    第五章 MVC之Bundle详解
  • 原文地址:https://www.cnblogs.com/xyq0220/p/14026941.html
Copyright © 2020-2023  润新知