题意:
解法:
令dep[ x] 表示点x到根的距离,
令L[ x] 和R[ x] 表示dfs序中x的范围[ L, R] .
对于查询( x, k) , 可以变为:
在[ L[ x] , R[ x] ] 范围内,
所有dep[ i] 中>= dep[ x] + k的和, 减去cnt* dep[ x] , cnt是满足条件点的数量
可以将[ L[ x] , R[ x] ] 范围内所有数建立权值线段树做,
因为有多组查询, 那么在序列上建立可持久化前缀权值线段树即可.
code:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define PI pair<ll,int>
const int maxm= 1e6 + 5 ;
const ll Maa= 2e18 ;
int head[ maxm] , nt[ maxm<< 1 ] , to[ maxm<< 1 ] , w[ maxm<< 1 ] , cnt;
int lc[ maxm* 40 ] , rc[ maxm* 40 ] , num[ maxm* 40 ] ;
ll sum[ maxm* 40 ] ;
int L[ maxm] , R[ maxm] , rk[ maxm] , idx;
int rt[ maxm] , tot;
ll dep[ maxm] ;
int n, q;
void add ( int x, int y, int z) {
cnt++ ; nt[ cnt] = head[ x] ; head[ x] = cnt; to[ cnt] = y; w[ cnt] = z;
}
void dfs ( int x, int fa) {
L[ x] = ++ idx;
rk[ idx] = x;
for ( int i= head[ x] ; i; i= nt[ i] ) {
int v= to[ i] ;
if ( v== fa) continue ;
dep[ v] = dep[ x] + w[ i] ;
dfs ( v, x) ;
}
R[ x] = idx;
}
void update ( ll x, ll val, ll l, ll r, int & k, int last) {
k= ++ tot;
lc[ k] = lc[ last] ;
rc[ k] = rc[ last] ;
sum[ k] = sum[ last] + val;
num[ k] = num[ last] + 1 ;
if ( l== r) return ;
ll mid= ( l+ r) / 2 ;
if ( x<= mid) update ( x, val, l, mid, lc[ k] , lc[ last] ) ;
else update ( x, val, mid+ 1 , r, rc[ k] , rc[ last] ) ;
}
PI ask ( ll st, ll ed, ll l, ll r, int x, int y) {
if ( st<= l&& ed>= r) return { sum[ y] - sum[ x] , num[ y] - num[ x] } ;
ll mid= ( l+ r) / 2 ;
PI ans= { 0LL , 0 } ;
PI temp;
if ( st<= mid) {
temp= ask ( st, ed, l, mid, lc[ x] , lc[ y] ) ;
ans. first+ = temp. first;
ans. second+ = temp. second;
}
if ( ed> mid) {
temp= ask ( st, ed, mid+ 1 , r, rc[ x] , rc[ y] ) ;
ans. first+ = temp. first;
ans. second+ = temp. second;
}
return ans;
}
signed main ( ) {
ios:: sync_with_stdio ( 0 ) ;
cin>> n;
for ( int i= 1 ; i< n; i++ ) {
int p, d; cin>> p>> d;
add ( p, i+ 1 , d) ;
add ( i+ 1 , p, d) ;
}
dfs ( 1 , 1 ) ;
for ( int i= 1 ; i<= n; i++ ) {
update ( dep[ rk[ i] ] , dep[ rk[ i] ] , 0 , Maa, rt[ i] , rt[ i- 1 ] ) ;
}
cin>> q;
while ( q-- ) {
int x, k; cin>> x>> k;
int L1= L[ x] - 1 , R1= R[ x] ;
PI ans= ask ( dep[ x] + k, Maa, 0 , Maa, rt[ L1] , rt[ R1] ) ;
ans. first- = 1ll * dep[ x] * ans. second;
cout<< ans. first<< endl;
}
return 0 ;
}