zoukankan      html  css  js  c++  java
  • 【HDU5421】Victor and String(回文树)

    【HDU5421】Victor and String(回文树)

    题面

    Vjudge
    大意:
    你需要支持以下操作:
    动态在前端插入一个字符
    动态在后端插入一个字符
    回答当前本质不同的回文串个数
    回答当前回文串个数

    题解

    回文树前端插入的操作,学一学感觉并不难?
    额外维护一下一个前端插入的(last)
    然后就和后端插入一模一样,前端插入时就是前端插入的(last)
    唯一会产生的影响的就是当前字符差完后,
    发现现在的(last)就是整个串,那么就要更新另外一端的(last)为当前这一端的(last)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 222222
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Node
    {
    	int son[26],ff;
    	int len,dep;
    }t[MAX];
    char s[MAX];
    ll ans;
    int tot,l,r,pre,suf,n;
    void init()
    {
    	l=1e5,r=l-1;memset(s,'',sizeof(s));
    	memset(t,0,sizeof(t));ans=0;
    	t[pre=suf=0].ff=t[tot=1].ff=1;t[1].len=-1;
    }
    void extend(int c,int n,int &last,int op)
    {
    	int p=last;
    	while(s[n]!=s[n-op*t[p].len-op])p=t[p].ff;
    	if(!t[p].son[c])
    	{
    		int v=++tot,k=t[p].ff;t[v].len=t[p].len+2;
    		while(s[n]!=s[n-op*t[k].len-op])k=t[k].ff;
    		t[v].ff=t[k].son[c];t[p].son[c]=v;
    		t[v].dep=t[t[v].ff].dep+1;
    	}
    	last=t[p].son[c];ans+=t[last].dep;
    	if(t[last].len==r-l+1)pre=suf=last;
    }
    int main()
    {
    	while(scanf("%d",&n)!=EOF)
    	{
    		init();
    		while(n--)
    		{
    			int opt=read();
    			if(opt<=2)
    			{
    				char c=getchar();
    				if(opt==1)s[--l]=c,extend(c-97,l,pre,-1);
    				else s[++r]=c,extend(c-97,r,suf,1);
    			}
    			else if(opt==3)printf("%d
    ",tot-1);
    			else printf("%lld
    ",ans);
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    NET 获取实例所表示的日期是星期几
    NET npoi 保存文件
    快速排序
    JAVA poi 合并单元格
    JAVA poi 帮助类
    JAVA 字符串编码转换
    NET npoi 合并单元值处理
    NET npoi帮助类
    Task的暂停,继续,取消
    .net ref与out之间区别
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9210996.html
Copyright © 2011-2022 走看看