2017 计蒜之道 初赛 第五场 D. UCloud 的安全秘钥(困难)

Posted Fighting Heart

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017 计蒜之道 初赛 第五场 D. UCloud 的安全秘钥(困难)相关的知识,希望对你有一定的参考价值。

小数据打表,大数据暴力。

导致超时的主要原因是$m$小的询问次数太多,可以把$m≤10$的答案直接暴力打表存起来,$m>10$的用$C$题的方法即可。

#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];

map<vector<int>,int>ans;

void work()
{
	vector<int>vv;
	for(int i=1;i<=m;i++)
	{
		vv.push_back(t[i]);
	}
	sort(vv.begin(),vv.end());
	printf("%d\n",ans[vv]);
}

int main()
{
	scanf("%d",&n);

	for(int i=1;i<=n;i++) scanf("%d",&s[i]);

	for(int i=1;i<=n;i++)
	{
		vector<int>vv;
		for(int j=i;j<=i+10-1;j++)
		{
			vv.push_back(s[j]);
			sort(vv.begin(),vv.end());
			ans[vv]++;
		}
	}

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

		if(m<=10)
		{
			work();
			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 计蒜之道 初赛 第五场 D. UCloud 的安全秘钥(困难)的主要内容,如果未能解决你的问题,请参考以下文章

2017 计蒜之道 初赛 第五场 B. UCloud 的安全秘钥(简单)

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

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

2018 计蒜之道 初赛 第五场

计蒜之道第五场C题

2017 计蒜之道 初赛 第三场 D. 腾讯狼人杀 (点边都带权的最大密度子图)