[BJOI2014]大融合

题意不难理解,看似非常简单的一道题,但是里面需要细想的东西还是挺多的,感觉想通过还是有一定难度的,踩了一些坑,记录一下吧~

题目

小强要在 N个孤立的星球上建立起一套通信系统。这套通信系统就是连接 N个点的一个树。
这个树的边是一条一条添加上去的。
在某个时刻,一条边的负载就是它所在的当前能够联通的树上路过它的简单路径的数量。
例如,在上图中,现在一共有了 5条边。其中,(3,8)这条边的负载是 6,因为有六条简单路径 2−3−8,2−3−8−7,3−8,3−8−7,4−3−8,4−3−8−7 路过了 (3,8)。
现在,你的任务就是随着边的添加,动态的回答小强对于某些边的负载的询问。

输入格式
第一行包含两个整数 N,Q,表示星球的数量和操作的数量。星球从 1开始编号。
接下来的 Q行,每行是如下两种格式之一:
A x y 表示在 x和 y 之间连一条边。保证之前 x 和 y是不联通的。
Q x y 表示询问 (x,y)这条边上的负载。保证 x 和 y之间有一条边。

输出格式
对每个查询操作,输出被查询的边的负载。
数据范围1≤N,Q≤100000

解决方法

  1. 从题目中可以看出,我们最后所有边都连接后,形成的是一个森林(可能会有好几棵树,所以需要建立好几棵树~),所以我们不妨先假设所有A中的边都已经连接,就可以将整张图的森林建立起来,来确定每个点的父节点,dep值,同时完成树链剖分
  2. 初始化操作:1.并查集的两个基本的初始化操作(p[i=i],cnt[i]=1)2.树状数组中每个点u[i]=1(u[]的含义在下文有详细的介绍),我们这一步的初始化通过找到上文里建立的每一棵树的根节点,记这个点为root,有两个属性id[root](在树链剖分中的得到的dfs序)sz[root](以root为根节点的子树的节点数量,那么这棵树最后一个节点的dfs序就为id[root]+sz[root]-1,所以通过树状数组的操作add_tree(id[root],1),add_tree(id[root]+sz[root],-1)来完成初始化(这道题里树状数组的sum_tree(t)含义是求id值为1-t的节点之和)
  3. 假设询问(a,b)边上的负载,计算答案的思路如下:首先可以肯定a,b在同一个并查集中,记这个并查集的父节点为pa(一个点所在并查集的父节点和这个点在森林中的父节点在我的代码中不是一一对应的!),我们在之前每次维护并查集时设置一个cnt[pa]来计算当前并查集中点的数量;然后因为整张图是一个森林且a,b间存在一条边,所以a,b间的关系必定为父子,也就是说我们可以通过dep确定a,b中谁是子节点(dep值小
  • 18
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值