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