题意:
给定长度为n的序列a,长度为m的序列b,一个整数p,
问有多少个位置q,满足a[q],a[q+p],a[q+2p],a[q+3p]…a[q+(m-1)p]构成的可重集与b[]相同。
输出所有满足条件的位置。
数据范围:1<=n,m,p<=2e5,a(i),b(i)<=1e9
解法:
按%p可以将序列分成p组,
每组尺取计算是否满足条件即可.
如何判断两个序列是否相同呢?
可以用map维护.
ps:
代码里面直接用map比较的,但是最好不要直接用等号判断.
code:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=3e5+5;
int a[maxm];
int b[maxm];
int n,m,p;
vector<int>ans;
map<int,int>B;
void cal(int st){
map<int,int>mp;
for(int i=st;i<=n;i+=p){
mp[a[i]]++;
if(i>st+(m-1)*p){
int x=a[i-m*p];
mp[x]--;
if(mp[x]==0){
mp.erase(x);
}
}
if(i>=st+(m-1)*p){
if(mp==B){
ans.push_back(i-(m-1)*p);
}
}
}
}
void solve(){
cin>>n>>m>>p;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=m;i++)cin>>b[i];
for(int i=1;i<=m;i++)B[b[i]]++;
for(int i=1;i<=p;i++){
cal(i);
}
sort(ans.begin(),ans.end());
cout<<ans.size()<<endl;
for(auto i:ans){
cout<<i<<' ';
}
cout<<endl;
}
signed main(){
ios::sync_with_stdio(0);
solve();
return 0;
}