暴力。
$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 "); 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 ",ans); } return 0; }