bzoj3940&&bzoj3942 Ac自动机||kpm算法

方法就是维护一个动态栈 记录栈的每一位匹配到串的哪一位的编号 第一道kmp第二道ac自动机 自己理会
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1000055;
char stack[M],s[M],t[M],f[M],next[M];
int len,top;
void getfail(){
    for(int i=1;i<len;i++){
        int j=f[i];
        while(j&&t[i]!=t[j]) j=f[j];
        f[i+1]=(t[i]==t[j]?j+1:0);
    }
}
int main()
{
    scanf("%s %s",s,t);
    int L=strlen(s); len=strlen(t); getfail(); 
    for(int i=0;i<L;i++){
        stack[++top]=s[i];
        int j=next[top-1];
        while(j&&t[j]!=stack[top]) j=f[j];
        if(t[j]==stack[top]) j++;
        next[top]=j;
        if(j==len) top-=len;
    }
    for(int i=1;i<=top;i++) printf("%c",stack[i]);
    return 0;
}
View Code
//同bzoj3942 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int size=27,M=100055;
char s[M],T[M],stack[M];
int next[M],top,n;
struct node{
    int sum,a[M][27],last[M],fail[M],val[M];
    int id(char s) {return s-'a'+1;}
    void insert(char s[]){
        int k=0,L=strlen(s);
        for(int i=0;i<L;i++){
            int now=id(s[i]);
            if(!a[k][now]) a[k][now]=++sum;
            k=a[k][now];
        }
        val[k]=L;
    }
    void getfail(){
        int q[M],k=0,head=0,tail=0;
        for(int i=1;i<=26;i++){
            int now=a[0][i];
            if(now) q[tail++]=now;
        }
        while(head!=tail){
            int x=q[head++];
            for(int i=1;i<=26;i++){
                int now=a[x][i];
                if(!now) { a[x][i]=a[fail[x]][i];continue;}
                q[tail++]=now;
                fail[now]=a[fail[x]][i];
                last[now]=val[fail[now]]?fail[now]:last[fail[now]];
            }
        }
    }
    void Ac_boy(){
        int now=0,L=strlen(T);
        for(int i=0;i<L;i++){
            int d=id(T[i]);
            stack[top]=T[i];
            now=a[now][d];
            next[top]=now;
            if(val[now]) top-=val[now],now=next[top];
            else if(last[now]) top-=val[last[now]],now=next[top];
            top++;
        }
    }
}node;
int main()
{
    scanf("%s",T);
    int n; scanf("%d",&n);
    while(n--) scanf("%s",s),node.insert(s);
    node.getfail(); node.Ac_boy();
    for(int i=0;i<top;i++) putchar(stack[i]);
    return 0;
}
View Code

 

posted @ 2017-05-23 14:38  友人Aqwq  阅读(199)  评论(0编辑  收藏  举报