暴力。
$O(m*n)$的算法可以通过此题,每次询问$O(m)$扫$S$数组,统计不同数字的个数,每次移动最多只会变化两个数字,如果不同数字个数为$0$,那么答案加$1$。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cmath>
using namespace std;
int n,m;
int s[100010];
int t[100010];
int m1[100010];
int m2[100010];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&s[i]);
int Q; scanf("%d",&Q);
while(Q--)
{
scanf("%d",&m);
for(int i=1;i<=m;i++) scanf("%d",&t[i]);
if(m>n)
{
printf("0\n");
continue;
}
memset(m1,0,sizeof m1);
memset(m2,0,sizeof m2);
for(int i=1;i<=m;i++) m1[s[i]]++, m2[t[i]]++;
int bu = 0;
for(int i=1;i<=n;i++) if(m1[i]!=m2[i]) bu++;
int ans = 0;
if(bu == 0) ans++;
for(int i=m+1;i<=n;i++)
{
int pre = i-m;
int now = i;
if(m1[s[pre]] == m2[s[pre]]) bu++;
else if(m1[s[pre]]-1 == m2[s[pre]]) bu--;
m1[s[pre]]--;
if(m1[s[now]] == m2[s[now]]) bu++;
else if(m1[s[now]]+1 == m2[s[now]]) bu--;
m1[s[now]]++;
if(bu == 0) ans++;
}
printf("%d\n",ans);
}
return 0;
}