题意:有 n n n个点, m m m条边,每条边有一个容量的上下限为 [ l i , r i ] [l_i,r_i] [li,ri],现在要给所有边一个统一的容量,使得可以从 1 1 1走到 n n n节点,问这样的容量有多少种取值。
首先可以对所有的 l , r l,r l,r离散化,当然这里我们需要像扫描线一样将一个点表示成一个区间,一个左闭右开的区间,所以将所有的 r + 1 r+1 r+1,然后对线段树上的每个节点开一个vector,用来保存满足该点取值的边的信息。
然后对于若干次的加边看做向线段树上对应的值域节点push一条边。
一次查询,从线段树的首节点开始,向下一直走,跑到一个节点将这个点包含的所有边放到并查集中,那么只要1和n此时处于并查集的同一块中,是不是就说明这一段值域就全部可以是合法情况,否则的话继续向左右儿子走。并查集的合并不可以路径压缩,因为线段树回溯的时候需要撤销掉操作,所以合并只可以按秩合并,将节点个数少的添加到个数多的里,同时记录该次合并的儿子节点,及父亲节点,还有合并前父亲节点包含的节点个数,回溯的时候撤销并查集的合并。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
struct Node{
int u,v,l,r;
}a[maxn];
int b