luogu2463 [SDOI2008]Sandy的卡片

先差分一下,钦定一个模式串,答案是这个模式串的所有后缀与其它串的最小的相同的的最大的。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n, a[1005][1005], len[1005], nxt[1005], ans=0;
void getNxt(int m){
	memset(nxt, -1, sizeof(nxt));
	int i=0, j;
	nxt[0] = j = -1;
	while(i<len[0]-m){
		if(j==-1 || a[0][i+m]==a[0][j+m])	nxt[++i] = ++j;
		else	j = nxt[j];
	}
}
int kmp(int m, int t){
	int i=0, j=0, tmp=0;
	while(i<len[t]){
		if(j==-1 || a[0][j+m]==a[t][i])	++i, ++j;
		else	j = nxt[j];
		tmp = max(tmp, j);
	}
	return tmp;
}
int main(){
	cin>>n;
	for(int i=0; i<n; i++){
		scanf("%d", &len[i]);
		for(int j=0; j<len[i]; j++)	scanf("%d", &a[i][j]);
		for(int j=0; j<len[i]-1; j++)	a[i][j] = a[i][j+1] - a[i][j];
		len[i]--;
	}
	for(int i=0; i<len[0]; i++){
		int tmpp=0x3f3f3f3f;
		getNxt(i);
		for(int j=1; j<n; j++)
			tmpp = min(tmpp, kmp(i, j));
		ans = max(tmpp, ans);
	}
	cout<<ans+1<<endl;
	return 0;
}
原文地址:https://www.cnblogs.com/poorpool/p/8270070.html