【问题描述】
在微信朋友圈里,经常能够看到别人发出的动态。在朋友圈中,我们与朋友共同分享兴奋与喜悦,一起分担伤心与苦闷。朋友圈似乎让一切变得便捷起来。
米国的一个小镇也有类似微信的软件,名曰“微米”。注意微米在这里不是一个长度单位,而是一款社交软件。在这款社交软件里,这个小镇的居民可以足不出户地了解到每个朋友的生活状态,也可以发出动态与朋友们分享自己的生活乐趣。
米国的工程师Sarah想统计一下小镇上的N个人每天能够收到多少朋友们的动态。在这一天中,这N个人(或他们之间)发生了如下的三类事件共M件:
S x:表示第x个人发出了一条动态。这时和他是直接朋友的人都可以收到这条动态;
L x y:表示第x个人与第y个人成为了直接朋友。当然在此操作前,这两个人不是直接朋友;
D x y:表示第x个人与第y个人断绝了朋友关系。当然在此操作前,这两个人一定是直接朋友。
请你编写一个程序,求出每个人在这一天内收到了多少动态。当然自己发出的动态不算在内。
在这一天开始前,这N个人任意两人之间都不是朋友关系。
【输入】
输入文件为hotspot.in。
输入的第一行为两个正整数N,M。
接下来的M行,每行描述一个事件。
【输出】
输出文件为hotspot.out。
输出仅一行,N个整数,第i个数表示第i个人总共收到的动态数。
【输入输出样例1】
hotspot.in hotspot.out
2 8
S 1
S 2
L 1 2
S 1
S 2
D 1 2
S 1
S 2
1 1
/*标记的创建:加边时,把这个边两个端点都减去对面端点此时已经发的动态数
标记的归还与删除:删边时要删除标记,删标记前b边上两个端点上的数要加给对方
*/
#include<cstdio>
#include<set>
#include<iostream>
using namespace std;
int n, m;
set<int> s[200020];
struct node{
int hot, rec;
} a[200020];
void connect(int x, int y){
s[x].insert(y);
s[y].insert(x);
a[x].rec -= a[y].hot;
a[y].rec -= a[x].hot;
}
void disconnect(int x, int y){
s[x].erase(y);
s[y].erase(x);
a[x].rec += a[y].hot;
a[y].rec += a[x].hot;
}
int main(){
cin >> n >> m;
for(int i = 1; i <= m; i++){
char ch;
int x, y;
cin >> ch;
if(ch == 'S'){
cin >> x;
a[x].hot++;
}
else if(ch == 'L'){
cin >> x >> y;
connect(x, y);
}
else{
cin >> x >> y;
disconnect(x, y);
}
}
for(int i = 1; i <= n; i++)
for(set<int> :: iterator it = s[i].begin(); it != s[i].end(); it++)
a[*it].rec += a[i].hot;
for(int i = 1; i <= n; i++)
cout << a[i].rec << " ";
cout << endl;
return 0;
}