4419: [Shoi2013]发微博

本文介绍了一个关于社交网络的好友关系与微博发布活动的模拟问题,并通过使用集合存储好友关系及采用前缀和思想来优化计算每位用户接收到的消息数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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,
勿忘国耻,振兴中华!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值