HDU - 5421:Victor and String (回文树,支持首尾插入新字符)
Posted hua-dong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 5421:Victor and String (回文树,支持首尾插入新字符)相关的知识,希望对你有一定的参考价值。
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 4Sample Output
4 5 4 5 11
题意:多组输入,开始字符串为空,支持4中操作: 1,在字符串首加字符; 2,在字符串尾加字符; 3,查询字符串不同本质的回文串个数; 4,查询回文串个数总和
思路:因为支持首尾加入,所以和常规的回文树有些不同。 参考了YYB的博客。 发现首尾互相影响,当且仅当整个字符串是回文串。 其他情况两头正常加即可。
#include<bits/stdc++.h> #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) #define rep2(i,a,b) for(int i=a;i>=b;i--) using namespace std; const int maxn=100010; struct PAT { struct node{ int len,num,fail,son[26]; }t[maxn]; int n,tot,s[maxn<<1],L,R,suf,pre; ll ans; void init() { memset(t,0,sizeof(t)); memset(s,-1,sizeof(s)); tot=1; L=100000; R=L-1; suf=pre=0; ans=0; t[1].len=-1; t[0].fail=t[1].fail=1; } void add(int c,int n,int &last,int op){ int p=last; s[n]=c; while(s[n]!=s[n-op-op*t[p].len]) p=t[p].fail; if(!t[p].son[c]){ int v=++tot,k=t[p].fail; while(s[n]!=s[n-op*t[k].len-op]) k=t[k].fail; t[v].fail=t[k].son[c]; t[v].len=t[p].len+2; t[v].num=t[t[v].fail].num+1; t[p].son[c]=v; } last=t[p].son[c]; ans+=t[last].num; if(t[last].len==R-L+1) suf=pre=last; } }T; int main() { int N; while(~scanf("%d",&N)){ T.init(); int opt; rep(i,1,N){ scanf("%d",&opt); char s[3]; if(opt==1){ scanf("%s",s); T.add(s[0]-‘a‘,--T.L,T.pre,-1); } else if(opt==2){ scanf("%s",s); T.add(s[0]-‘a‘,++T.R,T.suf,1); } else if(opt==3) printf("%d ",T.tot-1); else printf("%lld ",T.ans); } } return 0; }
以上是关于HDU - 5421:Victor and String (回文树,支持首尾插入新字符)的主要内容,如果未能解决你的问题,请参考以下文章
HDOJ 5421 Victor and String 回文串自己主动机
HDU 5418 Victor and World 允许多次经过的TSP
HDU 5418 Victor and World 状压DP的TSP问题
hdu 5418 Victor and World (状压dp)
HDU Victor and World (最短路+状态压缩)
BestCoder Round #52 (div.2) HDU 5418 Victor and World (DP+状态压缩)