2020 ICPC 威海 H. Message Bomb(差分)
阿新 • • 發佈:2021-10-13
題目連結
題意:
三種操作:
\(t\) \(a\) \(b\)
\((1)\)\(t=1\)時,\(a\)加入團體\(b\)
\((2)\)\(t=2\)時,\(a\)離開團體\(b\)
\((3)\)\(t=3\)時,\(a\)在團體\(b\)傳送一條訊息,團隊中除自己外的人都能接收到。
求每個人接收到的訊息條數。
思路:
\(set\)+差分。
\(set[i]\)儲存團體\(i\)中的人員。
\(sum[i]\)表示當前團體\(i\)接收到的訊息數,若\(k\)在時刻\(t_1\)加入團體\(i\),在\(t_2\)時離開團體\(i\)(中途\(k\)沒有發訊息),則接收到的訊息數\(=sum[i](t2時刻)-sum[i](t1時刻)\)
最後遍歷所有的\(set\)集合,更新結束時還沒有離開團體的人員接收到的訊息數。
code:
#include <iostream> #include <set> using namespace std; typedef long long ll; const int maxn = 1e6 + 10; set<int> st[maxn]; int n, m, s; int ans[maxn], sum[maxn]; int main(){ scanf("%d%d%d", &n, &m, &s); for(int i = 1; i <= s; i ++){ int a, b, c; scanf("%d%d%d", &a, &b, &c); if(a == 1){ ans[b] -= sum[c]; st[c].insert(b); } else if(a == 2){ ans[b] += sum[c]; st[c].erase(b); } else{ ans[b] --; sum[c] ++; } } for(int i = 1; i <= n; i ++){ for(int k : st[i])ans[k] += sum[i]; } for(int i = 1; i <= m; i ++)printf("%d\n", ans[i]); return 0; }