题目:
http://acm.hdu.edu.cn/showproblem.php?pid=5421
思路:
维护左右两端的节点指针,稍微修改一下就好了
(VictorWonder太强啦)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Palindromic_Tree{
static const int maxN=200005,CN=26;
int ch[maxN][CN];
int fail[maxN],len[maxN],num[maxN],cnt[maxN];
int str[maxN],L,R;
int last[2],tot;
ll sum;
int newnode(int _len){
tot++;
for (int i=0;i<CN;i++) ch[tot][i]=0;
len[tot]=_len;
num[tot]=cnt[tot]=0;
return tot;
}
void init(){
tot=-1; sum=0;
newnode(0); newnode(-1);
fail[0]=1; fail[1]=0;
last[0]=last[1]=0;
L=maxN/2; R=L-1;
str[L-1]=str[R+1]=-1;
}
int getfail(int x,bool right){
if (right)
while(str[R-1-len[x]]!=str[R])
x=fail[x];
else
while(str[L+1+len[x]]!=str[L])
x=fail[x];
return x;
}
void insert(int w,bool right){
if (right) str[++R]=w,str[R+1]=-1;
else str[--L]=w,str[L-1]=-1;
int u=getfail(last[right],right);
if (!ch[u][w]){
int v=newnode(len[u]+2);
fail[v]=ch[getfail(fail[u],right)][w];
ch[u][w]=v;
num[v]=num[fail[v]]+1;
}
last[right]=ch[u][w];
if (len[last[right]]==R-L+1) last[!right]=last[right];
cnt[last[right]]++;
sum+=num[last[right]];
}
void count(){
for (int i=tot;i>=0;i--) cnt[fail[i]]+=cnt[i];
}
}G;
int main(){
int n;
while(~scanf("%d",&n)){
G.init();
for (int i=1;i<=n;i++){
int tp; scanf("%d",&tp);
if (tp<=2){
char s[3];
scanf("%s",s);
G.insert(s[0]-'a',tp-1);
}
if (tp==3) printf("%d\n",G.tot-1);
if (tp==4) printf("%lld\n",G.sum);
}
}
}