4419: [Shoi2013]发微博

来源:互联网 发布:双十一淘宝购物技巧 编辑:程序博客网 时间:2024/05/29 07:41

Description

刚开通的SH微博共有n个用户(1..n标号),在短短一个月的时间内,用户们活动频繁,共有m条按时间顺序的记录:
! x   表示用户x发了一条微博;
+ x y 表示用户x和用户y成为了好友
- x y 表示用户x和用户y解除了好友关系
当一个用户发微博的时候,所有他的好友(直接关系)都会看到他的消息。
假设最开始所有人之间都不是好友关系,记录也都是合法的(即+ x y时x和y一定不是好友,而- x y时x和y一定是好友)。
问这m条记录发生之后,每个用户分别看到了多少条消息。
题解:
对于每个点用set存储它的好友关系。
但如果每发一次微博就统计一遍它的好友明显TLE。
于是TYB大佬告诉我可以用前缀和思想,
每加入一条边x->y,对于x,先减去y之前发的微博,
                                对于y,先减去x之前发的微博,
最后再加上发的微博数就可以求出这段时间内发的微博数了。
大概就是这样吧。(表述能力太菜,不懂的话可以看代码)
#include<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>#include<cstring>#include<set>using namespace std;const int N=200010;int n,m;struct node{set<int>q;}sa[N];char s[10];int sum[N],a[N];int main(){scanf("%d%d",&n,&m);//for(int i=1;i<=n;i++) sa[i].sum=0;int x,y;for(int i=1;i<=m;i++){scanf("%s",s);if(s[0]=='!'){scanf("%d",&x);a[x]++;/*for(set<int>::iterator j=sa[x].q.begin();j!=sa[x].q.end();j++)sa[*j].sum++;*/}if(s[0]=='+'){scanf("%d%d",&x,&y);sum[x]-=a[y];sum[y]-=a[x];sa[x].q.insert(y);sa[y].q.insert(x);}if(s[0]=='-'){scanf("%d%d",&x,&y);sum[x]+=a[y];sum[y]+=a[x];sa[x].q.erase(y);sa[y].q.erase(x);}}for(int x=1;x<=n;x++)for(set<int>::iterator j=sa[x].q.begin();j!=sa[x].q.end();j++)sum[x]+=a[*j];for(int i=1;i<n;i++)printf("%d ",sum[i]);printf("%d",sum[n]);}

打着打着突然拉起了防空警报吓死蒟蒻了,
才发现今天是9.18,
勿忘国耻,振兴中华!
原创粉丝点击