fold的毒瘤题

easy:

做法1.

可以仿照最小生成树的Kruskal做法, 将边权按照从小到大排序
对于每个询问: 按边权从小到大依次连接各个边, 同时用并查集维护特殊点的连通性, 一旦某条边加入后, 遍历所有的特殊点发现它们属于同一集合, 那么答案就是这条边的边权
复杂度: O(mlogm+qmn)

做法2.

对于某个权值 x , 如果权值不超过x的边能使所有特殊点连通, 那么对于 >x 的所有权值也一定能使特殊点连通, 满足单调性, 即二分性质
所以二分枚举 x , 用dfs判断特殊点是否连通, 如果特殊点连通, 那么将答案范围缩小至 [x,r] , 反之答案变为: [l,x1]
复杂度: O(nlogv)

mid:

答案很显然在最小生成树上取到, 这样就将原图转化成了一颗树
其中与hard一个很显然的不同就是: 点数不超过20个
所以只需要暴力求出这20个点两两之间路径上的最大值就好了
对于求: 两点之间树上路径最大值有2个做法:

做法1.

树链剖分 复杂度: O(log2n)
(我自己提交的树链剖分TLE了, 我本意是: 不卡这个log的)

做法2.

倍增求LCA的同时维护max[i][j]代表: 第i个节点到向上 2j 个节点的路径上的最大值
然后一边求LCA的同时求出到LCA的路径上的最大值, 两个最大值中较大的一个就是答案 复杂度: O(logn)
所以总的复杂度为: O(q20logn)

hard:

设定一个常数k
p>k 时, 这时候 %p=c 的点不超过k个, 向上面mid一样做就好了, 假设这样的询问有 q1 个, 时间复杂度: O(q1klogn)
pk 时, 将答案离线下来并按照p和c从小到大排序, 同时处理出所有p相同且c相同的区间询问
对于同一个 pi ci ,将所有 %pi=ci 的点, 两两( cj cj+p )求路径上的最大值, 并将这个相邻最大值更新到线段树上, 对于一个区间询问, 直接从线段树上获得 [l,r] 的区间最值就好了
关于复杂度, 最坏情况就是每一个p和c都不相同, 然而p只有不超过k个
对于某个 pi , %pi=0,1,,pi1 的点一共是n个, 所以每个点只会被更新(或删除)到线段树上一次
假设这样的询问有 q2 个, 复杂度最坏情况: O(q2knlogn)
k=n 时, 总时间复杂度为: O(nnlogn)

你可能感兴趣的:(题解,题解)