B
考虑建出这个图的 $kruskal$ 重构树。
那么把一个区间靠岸可以看成把区间上面的点按照 kruskal 重构树上面的 dfs 序排序后用0的边权加相邻的两个点,那么一条边可以替换的就是在 kruskal 重构树上面的 LCA
然后考虑一个点成为 lca 有什么条件。那么一定是在他的两个子树里能选出一对点 $[x,y]$,使询问区间包含 $[x,y]$。
因此就要对于 $fa_s$ 每个儿子 $s$ 的子树内所有点 $u$,求出编号比 $u$ 大的,在 $s$ 子树外而在 $fa_s$ 子树内最小点。
以上是一个 upper_bound 的形式,考虑进行 dsu-on-tree。具体的,一个 $[x,y]$ 必定包含至少一个点不在重儿子子树内。所以只需对每个轻儿子的子树内的点 $v$,求出其它子树内 $v$ 的前驱后继即可。
`后由于区间无包含关系,所以可以类似于点减边容斥的形式,将包含相邻2个的贡献减去,于是就是二维数点,树状树组维护即可。
#include <bits/stdc++.h>
using namespace std;
vector<tuple<int,int,int> >vec;
int fa[200005];
vector<int>g[200005];
int ff(int x){
return fa[x]==x?x:fa[x]=ff(fa[x]);
}
set<int>ve[200005];
vector<pair<int,int> >G[200005];
void addd(int L,int R,int tp){
G[R].push_back({L,tp});
// cout<<L<<' '<<R<<' '<<tp<<'\n';
}
int W[200005];
void dfs(int u){
vector<pair<int,int> >pr;
for(int v:g[u]){
dfs(v);
}
if(g[u].size()){
if(ve[g[u][0]].size()<ve[g[u][1]].size()){
swap(g[u][0],g[u][1]);
}
swap(ve[g[u][0]],ve[u]);
for(int v:ve[g[u][1]]){
auto it=ve[u].lower_bound(v);
if(it!=ve[u].end()){
pr.push_back({v,(*it)});
}
if(it!=ve[u].begin()){
pr.push_back({(*prev(it)),v});
}
}
for(int v:ve[g[u][1]]){
ve[u].insert(v);
}
}else{
ve[u].insert(u);
}
sort(pr.begin(),pr.end());
for(int i=0;i<pr.size();i++){
addd(pr[i].first,pr[i].second,W[u]);
}
for(int i=1;i<pr.size();i++){
addd(pr[i-1].first,pr[i].second,-W[u]);
}
}
vector<pair<int,int> >qr[200005];
long long tr[200005];
void add(int pos,int val){
for(;pos<=100000;pos+=(pos&-pos)){
tr[pos]+=val;
}
}
long long ask(int pos){
long long ans=0;
for(;pos;pos-=(pos&-pos)){
ans+=tr[pos];
}
return ans;
}
long long ans[200005];
int main(){freopen("flow.in","r",stdin);freopen("flow.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int n,m,q;
cin>>n>>m>>q;
for(int i=1;i<=n;i++){
fa[i]=i;
}
long long all=0;
for(int i=1;i<=m;i++){
int u,v,c;
cin>>u>>v>>c;
u++;
v++;
vec.push_back({c,u,v});
}
sort(vec.begin(),vec.end());
int tot=n;
for(auto [w,u,v]:vec){
if(ff(u)!=ff(v)){
all+=w;
tot++;
g[tot].push_back(ff(u));
g[tot].push_back(ff(v));
fa[ff(v)]=fa[ff(u)]=fa[tot]=tot;
W[tot]=w;
// cout<<u<<' '<<v<<'\n';
}
}
dfs(tot);
for(int i=1;i<=q;i++){
int l,r;
cin>>l>>r;
l++;
r++;
qr[r].push_back({l,i});
}
for(int i=1;i<=n;i++){
for(auto [pos,val]:G[i]){
add(1,val);
add(pos+1,-val);
// cout<<pos<<' '<<val<<'\n';
}
for(auto [L,id]:qr[i]){
ans[id]=ask(L);
// cout<<L<<'-'<<id<<'\n';
}
}
for(int i=1;i<=q;i++){
cout<<all-ans[i]<<'\n';
}
return 0;
}