2017 计蒜之道 初赛 第五场 C. UCloud 的安全秘钥(中等)

暴力。

$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;
}
posted @ 2017-06-03 20:42 Fighting_Heart 阅读(...) 评论(...) 编辑 收藏