所以只需要用线段树合并一下就好了
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define x first
#define y second
using namespace std;
const int N = 5e5 + 10,M = N * 2;
typedef long long ll;
typedef pair<int,int> PII;
int head[N],to[M],last[M],w[M],cnt;
void add(int a,int b,int c){
to[++cnt] = b;
w[cnt] = c;
last[cnt] = head[a];
head[a] = cnt;
}
int depth[N],fa[N][22],dis[N];
void dfs(int x,int lastt){
fa[x][0] = lastt;
for(int i = head[x]; i != -1; i = last[i]){
int j = to[i];
if(j == lastt) continue;
depth[j] = depth[x] + 1;
dis[j] = dis[x] + w[i];
dfs(j,x);
}
}
int lca(int x,int y){
if(depth[x] > depth[y]) swap(x,y);
//depth[x] < depth[y]
int cha = depth[y] - depth[x];
for(int i = 20; i >= 0; i--){
if((1 << i) <= cha) cha -= 1 << i,y = fa[y][i];
}
if(x == y) return x;
for(int i = 20; i >= 0; i--){
int dx = fa[x][i],dy = fa[y][i];
if(dx != dy) x = dx,y = dy;
}
return fa[x][0];
}
bool cmp(int a,int b){
return depth[a] > depth[b];
}
PII unite(PII a,PII b){
int LCA[5];
LCA[1] = lca(a.x,b.x);
LCA[2] = lca(a.x,b.y);
LCA[3] = lca(a.y,b.x);
LCA[4] = lca(a.y,b.y);
sort(LCA + 1,LCA + 5,cmp);
return {LCA[1],LCA[2]};
}
PII P[N * 4];
void build(int s,int t,int p){
if(s == t){
scanf("%d%d",&P[p].x,&P[p].y);
return;
}
int mid = s + t >> 1;
build(s,mid,p * 2);
build(mid + 1,t,p * 2 + 1);
P[p] = unite(P[p * 2],P[p * 2 + 1]);
}
PII query(int s,int t,int p,int l,int r){
if(s >= l && t <= r){
return P[p];
}
int mid = s + t >> 1;
PII G = {0,0};
if(l <= mid) G = query(s,mid,p * 2,l,r);
if(mid < r){
if(G == make_pair(0,0)) G = query(mid + 1,t,p * 2 + 1,l,r);
else G = unite(G,query(mid + 1,t,p * 2 + 1,l,r));
}
return G;
}
int main(){
int n;
cin >> n;
memset(head,-1,sizeof head);
for(int i = 1; i <= n - 1; i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
dfs(1,0);
for(int i = 1; i <= 21; i++){
for(int x = 1; x <= n; x++)
fa[x][i] = fa[fa[x][i - 1]][i - 1];
}
int m;
cin >> m;
build(1,m,1);
int k;
cin >> k;
while(k--){
int x,y;
scanf("%d%d",&x,&y);
PII G = query(1,m,1,x,y);
int t = lca(G.x,G.y);
cout << dis[G.x] + dis[G.y] - 2 * dis[t] << endl;
}
return 0;
}