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,
勿忘国耻,振兴中华!