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≤x≤m,1≤y≤n) 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

 题意:n个群聊,m个人,q个操作,操作有三种

(1)第x个人加入了第y个群聊

(2)第x个人退出了第y个群聊

(3)第x个人在第y个群聊发了一条消息

问最后每个人收到的消息数(一个人可以加入多个群聊

思路:cnt[i] 存每个群聊当前的消息数,s[i] 存第 i 个人收到了多少条消息,用set[i] 记录第 i 个人所在的群聊。差分的思想:一个人加入群聊时减去该群聊之前的消息数,退出群聊时加上该群聊当前的消息数,最后加上未退出的群聊消息数

为什么没有想到?

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
const int mod = 1e9 + 7;

int cnt[N], s[N];
set<int>st[N];

int main() {
    int n, m, q, x, y, op;
    scanf("%d%d%d", &n, &m, &q);
    for(int i = 1; i <= q; ++i) {
        scanf("%d%d%d", &op, &x, &y);
        if(op == 1) st[x].insert(y), s[x] -= cnt[y];
        else if(op == 2) st[x].erase(y), s[x] += cnt[y];
        else cnt[y]++, s[x]--;
    }
    for(int i = 1; i <= m; ++i) {
        for(set<int>::iterator it = st[i].begin(); it != st[i].end(); ++it)
            s[i] += cnt[*it];
        printf("%d\n", s[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43871207/article/details/109355996
今日推荐