nowcoder19778 游戏

本文探讨了一种优化并查集处理大量在线游戏用户的方法。通过维护并查集,当用户上线或下线时,利用势能分析处理高度节点,记录影响,并在节点重新上线时进行合并操作,确保复杂度可控。同时,文中提到了处理下线用户时保持答案正确性的策略,以及在线朋友数量的维护,以避免错误的“钻回空壳”情况。
摘要由CSDN通过智能技术生成

链接

点击跳转

题解

维护一个并查集,每次一个人上线,我就暴力把这个人所在的集合根其相邻且在线的人的集合给合并

一个人下线,就直接把他所在的并查集的 s i z e − − size-- size

这样不好的一点在于,每次的代价都是 O ( d e g r e e ( x ) ) O(degree(x)) O(degree(x))的,如果他总是操作一个度数很大的点,就肯定会 T T T

由于所有的点的度数之和等于 2 m 2m 2m,所以度数大于 2 m \sqrt {2m} 2m 的点的个数不会超过 2 m \sqrt {2m} 2m

度数小的我仍然可以使用暴力做法

但是度数大的,我考虑下能不能优化

注意到我们加入一个点的时候:我要把在图上和这个点相邻的而且在线的人都和自己合并

突破点就在这个"在线"

因为每次操作只能造成一个点从不在线变成在线,这就给人一种势能分析的感觉,有些需要势能分析的题目,我们总是在一些操作中积累势能,在某些操作中释放势能。现在我要处理这些度数大的点,就需要找一种“释放势能”的操作。

显然,我要对每个度数大的点记录所有影响到他的修改。也就是,和他在图上相邻的点,如果被激活了,就会影响到他,我们记录这个影响,说的明白一点,对每个度数大的点记录被激活的邻点。

当这个度数大的点一直在沉睡的时候,我就记录那些上线的临点。在度数大的点突然醒来的那一刻,我就要考虑处理这些信息了。显然我只要挨个进行并查集合并就行了,然后把这些信息丢掉(必须丢掉才能释放势能)。

具体一点:当小点上线时,我就暴力处理。同时看一下他是否影响到了某些沉睡中的大点,如果影响了就记录一下,小点上线的复杂度是 O ( d e g r e e ( u ) ) = O ( m ) O(degree(u)) = O( \sqrt {m} ) O(degree(u))=O(m )的。大点苏醒时,先处理前面积累的信息(势能分析得到这一部分是 O ( n ) O(n) O(

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值