题目分析:将值离散化,建立权值线段树,从编号为1的点开始dfs,当遍历到u时,处理所有以u为终点的询问,然后添加u-v边的权值w到线段树中,深搜处理v,处理完以后将w从线段树中取出。
用sum记录区间和,pos记录区间最右端存在的数的位置,线段树维护这两个变量即可。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std ;
typedef long long LL ;
#pragma comment(linker, "/STACK:16777216")
#define rep( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define For( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )
#define clr( a , x ) memset ( a , x , sizeof a )
#define cpy( a , x ) memcpy ( a , x , sizeof a )
#define ls ( o << 1 )
#define rs ( o << 1 | 1 )
#define lson ls , l , m
#define rson rs , m + 1 , r
#define root 1 , 1 , cnt
#define mid ( ( l + r ) >> 1 )
#define rt o , l , r
const int MAXN = 200005 ;
const int MAXE = 400005 ;
struct Edge {
int v , c ;
Edge* next ;
} E[MAXE] , *H[MAXN] , *edge , *Q[MAXN] ;
int sum[MAXN << 2] ;
int pos[MAXN << 2] ;
int a[MAXN] , cnt ;
int ans[MAXN] ;
int n , q ;
void clear () {
cnt = 0 ;
edge = E ;
clr ( H , 0 ) ;
clr ( Q , 0 ) ;
clr ( sum , 0 ) ;
clr ( pos , 0 ) ;
}
void addedge ( int u , int v , int c , Edge* H[] ) {
edge -> v = v ;
edge -> c = c ;
edge -> next = H[u] ;
H[u] = edge ++ ;
}
void update ( int x , int v , int o , int l , int r ) {
while ( l < r ) {
int m = mid ;
if ( x <= m ) {
r = m ;
o = ls ;
} else {
l = m + 1 ;
o = rs ;
}
}
sum[o] += v ;
if ( sum[o] ) pos[o] = l ;
else pos[o] = 0 ;
while ( o > 1 ) {
o >>= 1 ;
sum[o] = sum[ls] + sum[rs] ;
pos[o] = max ( pos[ls] , pos[rs] ) ;
}
}
int query ( int R , int o , int l , int r ) {
if ( !pos[o] ) return -1 ;
if ( r <= R ) return a[pos[o]] ;
int m = mid ;
if ( R <= m ) return query ( R , lson ) ;
int ans = query ( R , rson ) ;
if ( ans == -1 ) ans = query ( R , lson ) ;
return ans ;
}
int unique ( int n ) {
int cnt = 1 ;
sort ( a + 1 , a + n + 1 ) ;
For ( i , 2 , n ) if ( a[i] != a[cnt] ) a[++ cnt] = a[i] ;
return cnt ;
}
int hash ( int x ) {
int l = 1 , r = cnt ;
while ( l < r ) {
int m = mid ;
if ( a[m] >= x ) r = m ;
else l = m + 1 ;
}
return l ;
}
void dfs ( int u , int fa = 0 ) {
travel ( e , Q , u ) ans[e -> v] = query ( hash ( e -> c ) , root ) ;
travel ( e , H , u ) {
int v = e -> v , c = hash ( e -> c ) ;
if ( v != fa ) {
update ( c , 1 , root ) ;
dfs ( v , u ) ;
update ( c , -1 , root ) ;
}
}
}
void solve () {
int x , y , c ;
clear () ;
scanf ( "%d" , &n ) ;
rep ( i , 1 , n ) {
scanf ( "%d%d%d" , &x , &y , &c ) ;
addedge ( x , y , c , H ) ;
addedge ( y , x , c , H ) ;
a[++ cnt] = c ;
}
scanf ( "%d" , &q ) ;
rep ( i , 0 , q ) {
scanf ( "%d%d" , &x , &y ) ;
addedge ( x , i , y , Q ) ;
a[++ cnt] = y ;
}
cnt = unique ( cnt ) ;
dfs ( 1 ) ;
rep ( i , 0 , q ) printf ( "%d\n" , ans[i] ) ;
}
int main () {
int T ;
scanf ( "%d" , &T ) ;
while ( T -- ) solve () ;
return 0 ;
}