题解:P10634 BZOJ2372 music
fish_love_cat · · 题解
我也许是完全不会 hash?怎么被奶龙题卡了一万年。
多倍经验。
考虑哈希,考虑暴力哈希怎么做。
首先把这个串给离散化一下,然后给每个元素上一个权,权乘上
容易发现不管是否离散化,每一类元素的
然后我们对每个元素开桶维护出现次数,于是我们每次新增和删除元素都可以
于是你发现哈希值可以
直接做就是
#include<bits/stdc++.h>
#define int long long
#define mod 998244353
#define base 131
using namespace std;
mt19937 rnd(754021);
int qpow(int a,int b=mod-2){
int ans=1;
while(b){
if(b&1)ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
int rk[30];
int sm[30];
int a[100005];
int b[25005];
int bs[30];
int bas=1;
int flc;
int n,m,s;
int qry(){
int flc=0;
int qwq=0;
for(int i=1;i<=s;i++)
if(sm[i]){
qwq++;
flc=(flc+bs[i]*rk[qwq]%mod)%mod;
}
return flc;
}
signed main(){
cin>>n>>m>>s;
if(n<m){
cout<<0;
return 0;
}
for(int i=1;i<=s;i++)
rk[i]=rnd();
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=m;i++)
cin>>b[i],
sm[b[i]]++,
bs[b[i]]=(bs[b[i]]+bas)%mod,
bas=bas*base%mod;
bas=1;
flc=qry();
memset(sm,0,sizeof sm);
memset(bs,0,sizeof bs);
for(int i=1;i<=m;i++)
sm[a[i]]++,
bs[a[i]]=(bs[a[i]]+bas)%mod,
bas=bas*base%mod;
bas=bas*qpow(base)%mod;
vector<int>ret;
if(qry()==flc)ret.push_back(1);
for(int i=m+1;i<=n;i++){
sm[a[i-m]]--;
bs[a[i-m]]+=mod-1;
bs[a[i-m]]%=mod;
for(int j=1;j<=s;j++)
bs[j]=bs[j]*qpow(base)%mod;
sm[a[i]]++;
bs[a[i]]=(bs[a[i]]+bas)%mod;
if(qry()==flc)ret.push_back(i-m+1);
}
cout<<ret.size()<<'\n';
for(int i:ret)cout<<i<<'\n';
return 0;
}
//「我想,你们整支种族要把大陆公用语重新学一次比较好喔。」
// 对方「咦?」地露出了疑惑的脸色。
// 在一点也不像没问题的状况下,摆出一点也不像没问题的脸,然后说自己「没问题」。
// 费奥多尔认为,这大概是她们没有正确理解语言的关系。
// 感觉她们对「没问题」的正确意义与使用方式都不了解。
// 他宁可相信是那样。