标签:hdu last start ant oca clu void stream orm
假设没有操作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 回文串自己主动机
标签:hdu last start ant oca clu void stream orm
原文地址:http://www.cnblogs.com/cxchanpin/p/6919706.html