• 回文自动机学习笔记


    毛子牛逼!

    回文自动机

     1 //bzoj4044
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 int q,_len,son[100010][4],len[100001],f[100001],fail[100001],pre[100001],num[100001],st[100001],tot,n,last,ans;
     9 char s[100001];
    10 int u(char ch){
    11     return ch=='A'?0:ch=='T'?1:ch=='C'?2:3;
    12 }
    13 int newnode(int l){
    14     for(int i=0;i<4;i++)son[tot][i]=0;
    15     len[tot]=l;
    16     return tot++;
    17 }
    18 void init(){
    19     tot=n=last=0;
    20     newnode(0);
    21     newnode(-1);
    22     fail[0]=1;
    23     st[0]=-1;
    24 }
    25 int get_fail(int u){
    26     while(st[n-len[u]-1]!=st[n])u=fail[u];
    27     return u;
    28 }
    29 void ins(int c){
    30     st[++n]=c;
    31     int now=get_fail(last);
    32     if(!son[now][c]){
    33         int newn=newnode(len[now]+2);
    34         fail[newn]=son[get_fail(fail[now])][c];
    35         if(len[newn]<=2)pre[newn]=fail[newn];
    36         else{
    37             int v=pre[now];
    38             while(st[n-len[v]-1]!=st[n]||(len[v]+2)*2>len[newn])v=fail[v];
    39             pre[newn]=son[v][c];
    40         }
    41         son[now][c]=newn;
    42     }
    43     last=son[now][c];
    44 }
    45 void dp(){
    46     int u,v;
    47     queue<int>q;
    48     for(int i=2;i<tot;i++){
    49         if(len[i]%2==1)f[i]=len[i];
    50     }
    51     q.push(0);
    52     f[0]=1;
    53     while(!q.empty()){
    54         u=q.front();
    55         q.pop();
    56         for(int i=0;i<4;i++){
    57             if(son[u][i]){
    58                 v=son[u][i];
    59                 f[v]=min(f[u]+1,len[v]/2-len[pre[v]]+f[pre[v]]+1);
    60                 ans=min(ans,_len-len[v]+f[v]);
    61                 q.push(v);
    62             }
    63         }
    64     }
    65 }
    66 int main(){
    67     scanf("%d",&q);
    68     while(q--){
    69         scanf("%s",s);
    70         init();
    71         ans=_len=strlen(s);
    72         for(int i=0;i<_len;i++){
    73             ins(u(s[i]));
    74         }
    75         dp();
    76         printf("%d
    ",ans);
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    转:va_list、va_start、va_arg、va_end的原理与使用
    学习Docker的记录
    Google Code 优秀的开源工具
    转载(程序在内存中运行的奥秘)
    C# 和 Java 之争之我见
    揭秘ASP.NET 2.0的Eval方法(转)
    IIS6.0 架构(二)
    IE6 position:fixed bug (固定窗口方法)(转载)
    用FileStream上传图片转换成二进制,在本地用行,传到服务器上去出现如下错误
    异常处理
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/9222929.html
Copyright © 2020-2023  润新知