1. 程式人生 > >2017 計蒜之道 初賽 第五場 C. UCloud 的安全秘鑰(中等)

2017 計蒜之道 初賽 第五場 C. UCloud 的安全秘鑰(中等)

移動 如果 space -m 變化 安全 ont con esp

暴力。

$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;
}

2017 計蒜之道 初賽 第五場 C. UCloud 的安全秘鑰(中等)