【GDOI2021PJ Day2T1】杂音密码(noise)

【GDOI2021PJ Day2T1】杂音密码(noise)

Description

【GDOI2021PJ Day2T1】杂音密码(noise)

Input

【GDOI2021PJ Day2T1】杂音密码(noise)

Output

【GDOI2021PJ Day2T1】杂音密码(noise)

Sample Input

样例输入1:
7 3
0 2 1 1 7
2 2 7 3 5 0 1
2 1 2
样例输入2:
7 3
0 2 1 1 7
0 1 6 0 1 0 1
1 2 3

Sample Output

8

题解

考场不会KMP的痛
把混合序列和杂音序列一减(注意处理一下模数),就是一道KMP模板题了,直接拿密码序列去匹配即可
But我考场不会KMP+没处理模数痛失80

CODE

#include<cstdio>
#include<string>
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define R register int
#define N 100005
#define ll long long
#define mo 256
using namespace std;
inline void read(int &x)
{
	x=0;int f=1;char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();x*=f;
}
int t,m,mi[N],hun[N<<1],n[N<<1],next[N<<1],a,b,c,d,e,s[N<<1],ans,ans1[N<<1];
int main()
{
	freopen("noise.in","r",stdin);
	freopen("noise.out","w",stdout);
	read(t);read(m);read(a);read(b);read(c);read(d);read(e);
	for (R i=1;i<=t;++i)
	{
		if (i==1) n[i]=a;
		else n[i]=(((n[i-1]<<b)+(n[i-1]>>c))%mo+d)%mo%e;
	}
	for (R i=1;i<=t;++i)
		read(hun[i]);
	for (R i=1;i<=t;++i)
		s[i]=(hun[i]-n[i]+mo)%mo;
	for (R i=1;i<=m;++i)
		read(mi[i]);
	for (R i=2,j=0;i<=m;++i)
	{
		while (j && mi[j+1]!=mi[i]) j=next[j];
		if (mi[j+1]==s[i]) ++j;next[i]=j;
	}
	for (R i=1,j=0;i<=t;++i)
	{
		while (j && mi[j+1]!=s[i]) j=next[j];
		if (mi[j+1]==s[i]) ++j;
		if (j==m) ans1[++ans]=i-m+1,j=next[j];
	}
	if (!ans) printf("wrong\n");
	else
	{
		printf("%d\n",ans);
		for (R i=1;i<=ans;++i)
			printf("%d ",ans1[i]);
		printf("\n");
	}
	return 0;
}
上一篇:KMP算法详解


下一篇:LeetCode5 求回文子串算法