今天是2018/4/4,DCDCBigBig的第三十一篇博文
回文自动机
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
int q,_len,son[100010][4],len[100001],f[100001],fail[100001],pre[100001],num[100001],st[100001],tot,n,last,ans;
char s[100001];
int u(char ch){
return ch=='A'?0:ch=='T'?1:ch=='C'?2:3;
}
int newnode(int l){
for(int i=0;i<4;i++)son[tot][i]=0;
len[tot]=l;
return tot++;
}
void init(){
tot=n=last=0;
newnode(0);
newnode(-1);
fail[0]=1;
st[0]=-1;
}
int get_fail(int u){
while(st[n-len[u]-1]!=st[n])u=fail[u];
return u;
}
void ins(int c){
st[++n]=c;
int now=get_fail(last);
if(!son[now][c]){
int newn=newnode(len[now]+2);
fail[newn]=son[get_fail(fail[now])][c];
if(len[newn]<=2)pre[newn]=fail[newn];
else{
int v=pre[now];
while(st[n-len[v]-1]!=st[n]||(len[v]+2)*2>len[newn])v=fail[v];
pre[newn]=son[v][c];
}
son[now][c]=newn;
}
last=son[now][c];
}
void dp(){
int u,v;
queue<int>q;
for(int i=2;i<tot;i++){
if(len[i]%2==1)f[i]=len[i];
}
q.push(0);
f[0]=1;
while(!q.empty()){
u=q.front();
q.pop();
for(int i=0;i<4;i++){
if(son[u][i]){
v=son[u][i];
f[v]=min(f[u]+1,len[v]/2-len[pre[v]]+f[pre[v]]+1);
ans=min(ans,_len-len[v]+f[v]);
q.push(v);
}
}
}
}
int main(){
scanf("%d",&q);
while(q--){
scanf("%s",s);
init();
ans=_len=strlen(s);
for(int i=0;i<_len;i++){
ins(u(s[i]));
}
dp();
printf("%d\n",ans);
}
return 0;
}
纯模板
struct PAM{
int son[100001][26],len[100001],fail[100001],cnt[100001],num[100001],last,tot,n,st[100001];
int newnode(int l){
cnt[++tot]=0;
num[tot]=0;
len[tot]=l;
return tot;
}
void init(){
memset(son,0,sizeof(son));
tot=n=last=0;
newnode(0);
newnode(-1);
st[0]='&';
fail[0]=1;
}
int get_fail(int u){
while(st[n-len[u]-1]!=st[u])u=fail[u];
return u;
}
void add(int ch){
st[++n]=ch;
int now=get_fail(last);
if(!son[now][ch]){
int newn=newnode(len[now]+2);
fail[newn]=son[get_fail(fail[now])][ch];
son[now][ch]=newn;
num[newn]=num[fail[newn]]+1;
}
last=son[now][ch];
cnt[last]++;
}
void count(){
for(int i=tot;i;i--){
cnt[fail[i]]+=cnt[i];
}
}
};