1. 程式人生 > >bzoj3940&&bzoj3942

bzoj3940&&bzoj3942

oid 分享 esp ide .get tchar %d [] truct

方法就是維護一個動態棧 記錄棧的每一位匹配到串的哪一位的編號 第一道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

bzoj3940&&bzoj3942