假设没有操作1,就是裸的回文串自己主动机......
能够从头部插入字符的回文串自己主动机,维护两个last点就好了.....
当整个串都是回文串的时候把两个last统一一下
6 1 a 1 b 2 a 2 c 3 4 8 1 a 2 a 2 a 1 a 3 1 b 3 4
4 5 4 5 11
/* ***********************************************
Author :CKboss
Created Time :2015年08月24日 星期一 10时32分04秒
File Name :HDOJ5421.cpp
************************************************ */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long int LL;
const int maxn=200100;
const int C=30;
int L,R;
int nxt[maxn][C];
int fail[maxn];
LL cnt[maxn];
LL num[maxn];
int len[maxn];
int s[maxn];
int last[2],p,n;
LL tot;
int newnode(int x)
{
for(int i=0;i<C;i++) nxt[p][i]=0;
num[p]=0; len[p]=x;
return p++;
}
void init()
{
p=0;
newnode(0); newnode(-1);
memset(s,-1,sizeof(s));
L=maxn/2; R=maxn/2-1;
last[0]=last[1]=0;
fail[0]=1;
tot=0;
}
/// d=0 add preffix d=1 add suffix
int getfail(int d,int x)
{
if(d==0) while(s[L+len[x]+1]!=s[L]) x=fail[x];
else if(d==1) while(s[R-len[x]-1]!=s[R]) x=fail[x];
return x;
}
void add(int d,int c)
{
c-=‘a‘;
if(d==0) s[--L]=c;
else s[++R]=c;
int cur=getfail(d,last[d]);
if(!nxt[cur][c])
{
int now=newnode(len[cur]+2);
fail[now]=nxt[getfail(d,fail[cur])][c];
nxt[cur][c]=now;
num[now]=num[fail[now]]+1;
}
last[d]=nxt[cur][c];
if(len[last[d]]==R-L+1) last[d^1]=last[d];
tot+=num[last[d]];
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int _;
while(scanf("%d",&_)!=EOF)
{
init();
while(_--)
{
int kind;
char ch[5];
scanf("%d",&kind);
if(kind<=2)
{
kind--;
scanf("%s",ch);
add(kind,ch[0]);
}
else if(kind==3) printf("%d\n",p-2);
else if(kind==4) printf("%lld\n",tot);
}
}
return 0;
}
HDOJ 5421 Victor and String 回文串自己主动机
原文:http://www.cnblogs.com/cxchanpin/p/6919706.html