2020CCPC威海站 : H Message Bomb

2020CCPC威海站 : H Message Bomb

一:题面:

H Message Bomb

While we enjoy chatting with friends on the internet, it is always annoying that we are overwhelmed by lots of messages in various chat groups. A great majority of these messages are actually not interesting to us, but we may miss some important notices if we silence these groups. How many messages do we receive from all online chat groups? Nobody has ever seriously gone into this question.

As an assistant researcher in the school of informatics, you are required to investigate the number of online messages we receive every day. We have already sampled n groups and m students. Every group contains a subset of the m students, which is possibly empty. Also, the members of the groups are constantly evolving; old members may quit, and new members may join in a chat group. Members can send messages in the group; the message is broadcast to all other members currently in the same group.

Now we have collected the log of these chat groups. The log is a sequence of events, which may be a student joining in a group, quitting a group, or sending a message in a group. Your task is to compute the total number of messages received by every student.

Input Specification:

The first line of the input contains three integers n,m,s (1≤n≤100000,1≤m≤200000,1≤s≤1000000), denoting the number of groups, the number of students and the number of events in the log.

The next s lines give the events in the log in chronological order. Each of them contains three integers t,x,y (t∈{1,2,3},1≤xm,1≤yn) specifying an event, which may fall into one of the following three categories:

  • If t=1, it means that the x-th student joined in the y-th group. It is guaranteed that the student was not in the group before.
  • If t=2, it means that the x-th student quitted the y-th group. It is guaranteed that the student was currently in the group.
  • If t=3, it means that the x-th student sent a message in the y-th group. It is guaranteed that the student was in the group now.

Initially, all groups were empty.

Output Specification:

Output m lines. The i-th line contains an integer, denoting the total number of messages the i-th student received.

Sample Input 1:

3 3 10
1 3 2
1 3 1
1 1 2
1 2 1
3 1 2
2 3 1
3 3 2
3 2 1
3 3 2
3 2 1

Sample Output 1:

2
0
1

Sample Input 2:

2 5 10
1 1 2
3 1 2
2 1 2
1 3 2
1 1 2
3 1 2
3 3 2
1 4 2
3 3 2
1 5 1

Sample Output 2:

2
0
1
1
0

二:解题思想

​ 记得当时赛场上开H题时是有一些小小的思路的,这题大概意思就是一群人分多个组,在不同的时间点,有人加入,有人退出,也有人给他所在的组其它人分发邮件,问:最后每个人共收到了多少份邮件?

​ 看到此题,我们队想到的做法有:差分,线段树之类的,但很明显,有插入和删除点在线段树中会非常复杂,所以差分就是这题解题的关键点。遗憾的是考场没有差分模板

​ 当然,这题不仅是差分那么简单,我给这道题的定义为:差分思想 + set优化,只有理解透差分的含义与思想才能将此题迎刃而解。

(一):差分

定义:原数组:s[i] ,差分数组 d[i]

1: d[i] = s[i] - s[i-1]
2: s[i] = ∑ i = 1 n \sum_{i=1}^n i=1nd[i]
3: 在 区间[ a, b ]内加上数c:
d[a]+c, d[b+1]-c

(二):将差分思想运用到实际题目中

​ 不妨这样思考,无论最后这个人在哪个组,都将这个组的累计邮件计入到该人的邮件数量上。 那么当在某一时间点这个人 i 加入到 a 组时,将他s[i] - cnt[a],即该组原来积累的邮件数,当他离开的时候,只需将s[i] + cnt[a],即为在这段时间内,他获得的邮件数。

​ 继续,当他在该组发邮件时,除他之外其余人的邮件数加1 ,即cnt[a]++, s[i]–即可

(三):AC代码

要注意的是:一个人可以同时加多个组

#include <bits/stdc++.h>
#define ll long long
using namespace std;

int n,m,s1;
int s[210000],cnt[110000];
set<int> sets[210000];   //存放 学生当前所在的组 

int main(){
	cin>>n>>m>>s1;
	while(s1--){
		int t,a,b;
		cin>>t>>a>>b;
		if(t==1){
			s[a] -= cnt[b];
			sets[a].insert(b);
		}
		else if(t==2){
			s[a] += cnt[b];
			sets[a].erase(b);
		}
		else{
			cnt[b]++;
			s[a]--;
		}
	}
	for(int i=1;i<=m;i++){
		set<int>::iterator j;
		for(j=sets[i].begin(); j!=sets[i].end(); j++){
			int p = *j;
			s[i] += cnt[p];
		}
		cout<<s[i]<<endl;		
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值