Xjz
Description
给定字符串
S
和
串
A
和串
A
=
求
S
有多少个子串与
Data Constraint
|S|,|T|≤106
Solution
这种题解题方向很明显,多半是
Hash
。
设
wi
表示与
i
位置上的数相同的前一个位置与它的距离,若两个子串的
那问题就简单了,用个指针表示
T
的第一个位置在
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,j,l) for(int i=j;i<=l;++i)
#define fd(i,j,l) for(int i=j;i>=l;--i)
using namespace std;
typedef long long ll;
const ll N=11e5,K=31,mo=998244353;
int T,C,n,m;
int s[N],t[N],last[N];
int dq[N],ut[N],ans[N];
ll q[N],xs[N];
bool kmp(int a,int b)
{return last[a]<last[b];}
inline int read()
{
int o=0; char ch=' ';
for(;ch<'0'||ch>'9';ch=getchar());
for(;ch>='0'&&ch<='9';ch=getchar())o=o*10+ch-48;
return o;
}
int main()
{
cin>>T>>C;
fo(tt,1,T){
cin>>n>>m;
q[1]=1;
fo(i,1,n)last[i]=dq[i]=0;
fo(i,2,n)q[i]=q[i-1]*K%mo;
fo(i,1,n)s[i]=read();
fo(i,1,m)t[i]=read();
fo(i,1,n)last[i]=dq[s[i]],dq[s[i]]=i,xs[i]=last[i]!=0?i-last[i]:0;
fo(i,1,n)dq[i]=0;
ll hash=0,h1=0;
fo(i,1,m)hash=(hash*K+i-(dq[t[i]]==0?i:dq[t[i]]))%mo,dq[t[i]]=i;
fo(i,1,n)ut[i]=i;
sort(ut+1,ut+n+1,kmp);
fo(i,1,m)h1=(h1*K+xs[i])%mo;
int oo=0,w=1;
if(h1==hash)ans[++oo]=1;
fo(i,2,n-m+1){
for(;last[ut[w]]<i&&w<=n;++w){
if(ut[w]<m+i-1)h1=(h1+mo-q[i+m-1-ut[w]]*xs[ut[w]]%mo)%mo;
xs[ut[w]]=0;
}
h1=(h1+mo-(xs[i-1])*q[m]%mo)%mo;
h1=h1*K%mo;
h1=(h1+xs[i+m-1])%mo;
if(h1==hash)ans[++oo]=i;
}
cout<<oo<<endl;
fo(i,1,oo)printf("%d ",ans[i]);
puts("");
}
}