H - Message Bomb Gym - 102798H

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了H - Message Bomb Gym - 102798H相关的知识,希望对你有一定的参考价值。

H - Message Bomb Gym - 102798H

题意:

有n个团队,m个人,s个操作
操作1:学生x加入y团队
操作2:学生x推出y团队
操作3:学生x在团队y发送一个信号,在团队y内的所有成员(除了x)都收到一个信号
所有操作结束后,问每个学生收到多少信号?
1≤n≤100000,1≤m≤200000,1≤s≤1000000)

题解:

我的思路一开始直接跑偏,都跑到树剖上,还好队友把我拉了回来
不要被数据范围所吓倒
我们用set< int >s来存每个团队有什么成员,v表示当前团队的分数,ans为每个成员的分数,具体实现为:当x加入团队y时,s[y]存入x,并且ans[x]减去v[y],因为v表示这个团队的信号数量,x刚加进去,之前的信号数量和他没有关系,所以要减去v[y],x推出团队时,ans[x]+=v[y],就是将团队的信号量加到个人上,x在团队y发信号,就直接v[y]加1,ans[x]减1(因为x不能接收自己的信号),相当于团队先帮大家存信号,然后再依次返还
所有操作结束后,对于每个团队,将该团队的信号量加到每个学生上,等下!!你可能会想,如果数据极端情况,每个学生都加入到了所有团队,这样的复杂度不就是O(n * m),铁超时,但其实并不是,因为操作熟练是由上线的,s<=1000000,如果所有操作都执行全部同学加入y团队,那么在一个团队内最多也就是1e6个人,其他团队都为空,也就是复杂度的上线其实是O(s),所以不会超时
签到题,想这么复杂干什么

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+9;
unordered_set<int>vec[maxn];
int ans[maxn];
int v[maxn];//每组的分数 
int main()
{
	int n,m,s;
	cin>>n>>m>>s;
	for(int i=1;i<=s;i++)
	{
		int t,x,y;
		scanf("%d%d%d",&t,&x,&y);
		if(t==1)
		{
			vec[y].insert(x);
			ans[x]-=v[y];
		}
		else if(t==2)
		{
			vec[y].erase(x);
			ans[x]+=v[y];
		}
		else if(t==3)
		{
			ans[x]--;
			v[y]++;
		}
	}
	for(int i=1;i<=n;i++){
		if(vec[i].size()==0)
		continue;
		for(auto j:vec[i]){
			ans[j]+=v[i];
		}
	}
	for(int i=1;i<=m;i++){
		printf("%d\\n",ans[i]);
	}
}

以上是关于H - Message Bomb Gym - 102798H的主要内容,如果未能解决你的问题,请参考以下文章

H - Hamiltonian Hypercube Gym - 101170H

hdu 3555 Bomb 数位DP

C ++ - 向量迭代器+偏移超出范围

HDU 3555Bomb 数位DP

Codeforces Gym 101174 J Risky Lottery 计算方法 逼近求值 dfs

gym-101343H-Give Me This Pizza