【COCI 2011-2012 contest#4】decode(本质匹配KMP)

题意:
总字符数均 < = 1 e 6 <=1e6 <=1e6的两篇文章 S , T S,T S,T,其中把 T T T的每个单词换成另一个单词并且两个不同的单词不能换成同一个单词后(可以不变),与 S S S中的一段匹配,求最早的可能匹配的位置。

题解:
对于单词建 t r i e trie trie树之后就可以把一个单词离散成一个编号。为啥不哈希啊不卡内存还好写
然后使用本质匹配KMP,即每个点的值为前面第一个和它单词相同的位置与当前位置的距离,然后就完了。

#include<bits/stdc++.h>
#define LL long long
#define maxn 1000006
using namespace std;

int n=1,m=1;
char S[maxn];
int s[maxn],t[maxn],nxt[maxn],pr[maxn];
int tr[maxn][26],tot;

int main(){
	for(;scanf("%s",S) && S[0]!='$';){
		int p = 0 , len = strlen(S);
		for(int i=0,v;i<len;i++){
			if(!tr[p][v = S[i]-'0']) tr[p][v] = ++tot;
			p = tr[p][v];
		}
		s[n] = n - pr[p] , pr[p] = n;
		n++;
	}
	memset(pr,0,sizeof pr);
	for(;scanf("%s",S) && S[0]!='$';){
		int p = 0 , len = strlen(S);
		for(int i=0,v;i<len;i++){
			if(!tr[p][v = S[i]-'0']) tr[p][v] = ++tot;
			p = tr[p][v];
		}
		t[m] = m - pr[p] , pr[p] = m;
		m++;
	}
	for(int j=0,k=1;k<m;)
		if(j == 0 || (min(t[j],j) == min(t[k],j))) nxt[++k] = ++j;
		else j = nxt[j];
	for(int i=1,j=1;i<n;i++,j++){
		if(j == m){
			printf("%d\n",i-m+1);
			return 0;
		}
		while(j!=0 && min(t[j],j) != min(s[i],j)) j=nxt[j];
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值