KMP <--可能是假的KMP

来自蒟蒻XXJ的做题记录

在Menci OJ写了一发KMP居然挂掉了……

然后就想着拿SAM把这个板子给艹过去……

成功MLE……

#include<bits/stdc++.h>
#define mem(i,j) memset(i,j,sizeof(i))
#define mcy(i,j) memcpy(i,j,sizeof(i))
using namespace std;
const int MAXN=2000010;
char s1[MAXN],s2[MAXN];
int l1,l2;
int b[MAXN];
int id(char c){
	if(c>='a'&&c<='z') return c-'a';
	else return c-'A'+26;
}
struct SAM{
	int trans[MAXN][26*2],lth[MAXN],r[MAXN],fa[MAXN];
	int last,cnt;
	SAM(){
		cnt=0;last=++cnt;
		mem(trans,0);mem(lth,0);mem(r,0);mem(fa,0);
	}
	void extend(int c){
		int np=++cnt,p=last;last=cnt;
		lth[np]=lth[p]+1;
		for(;p&&!trans[p][c];p=fa[p]) trans[p][c]=np;
		if(!p) fa[np]=1;
		else{
			int q=trans[p][c];
			if(lth[q]==lth[p]+1) fa[np]=q;
			else{
				int nq=++cnt;
				lth[nq]=lth[p]+1;
				mcy(trans[nq],trans[q]);
				fa[nq]=fa[q];
				fa[q]=fa[np]=nq;
				for(;p&&trans[p][c]==q;p=fa[p]) trans[p][c]=nq;
			}
		}
	}
	void build(char c[]){
		int len=strlen(c);
		for(int i=0;i<len;i++){
			extend(id(c[i]));
		}
	}
}sam;
int rk[MAXN];
bool cmp(int i,int j){
	return sam.lth[i]>sam.lth[j];
}
void init(){
	for(int i=1;i<=sam.cnt;i++) ++b[sam.lth[i]];
	for(int i=1;i<=l1;i++) b[i]+=b[i-1];
	for(int i=1;i<=sam.cnt;i++) rk[b[sam.lth[i]]--]=i;
	int now=1;
	for(int i=0;i<l1;i++){
		now=sam.trans[now][id(s1[i])];
		++sam.r[now];
	}
	for(int i=sam.cnt;i;--i){
		int ind=rk[i];
		if(!sam.fa[ind]) continue;
		sam.r[sam.fa[ind]]+=sam.r[ind];
	}
}
void input(){
	scanf("%s",s1);scanf("%s",s2);
	l1=strlen(s1);l2=strlen(s2);
	sam.build(s1);
	init();
}
void xxj(){
	int now(1);
	for(int i=0;i<l2;i++){
		if(!sam.trans[now][id(s2[i])]) cout<<0<<endl,exit(0);
		now=sam.trans[now][id(s2[i])];
	}
	cout<<sam.r[now]<<endl;
}

int main(){
//	freopen("1.in","r",stdin);
//	freopen("2.in","w",stdout);
	input();
	xxj();
	return 0;
}
posted @ 2017-03-30 09:44  Xiaojian_xiang  阅读(186)  评论(0编辑  收藏  举报