1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
#include <bits/stdc++.h> #define maxn 800005 #define int long long #define lson(x) (x << 1) #define rson(x) (x << 1 | 1) using namespace std;
template<typename T> void Print(T value){ std::cout << value << '\n'; } template<typename Head, typename... Rail> void Print(Head head, Rail... rail){ std::cout << head << ", "; Print(rail...); }
int read(){ int x = 0; char ch = getchar(); while(ch < '0' || ch > '9') ch = getchar(); while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x; }
struct SegTree{ struct Node{ int lf, rt, mx, mn; } tr[maxn]; void Build(int now, int lf, int rt, int a[]){ tr[now].lf = lf; tr[now].rt = rt; if(lf == rt){ tr[now].mx = tr[now].mn = a[lf]; return; } int mid = (lf + rt) / 2; Build(lson(now), lf, mid, a); Build(rson(now), mid + 1, rt, a); tr[now].mx = max(tr[lson(now)].mx, tr[rson(now)].mx); tr[now].mn = min(tr[lson(now)].mn, tr[rson(now)].mn); } int Query(int now, int lf, int rt, int k){ if(tr[now].lf >= lf && tr[now].rt <= rt){ if(tr[now].mn >= k){ return tr[now].rt - tr[now].lf + 1; } else if(tr[now].mx < k){ return 0; } else{ return Query(lson(now), lf, rt, k) + Query(rson(now), lf, rt, k); } } if(tr[now].lf > rt || tr[now].rt < lf) return 0; return Query(lson(now), lf, rt, k) + Query(rson(now), lf, rt, k); } } mt; int n, q, t[maxn], dfnt[maxn]; int cnt, in[maxn], out[maxn], id[maxn]; vector<int> G[maxn];
int tt, d[maxn], f[maxn][35]; void pre(int now){ tt = (int)(log(n) / log(2)) + 1; queue<int> q1; q1.push(now); d[now] = 1; while(!q1.empty()) { int x = q1.front(); q1.pop(); for(auto nxt : G[x]){ if(d[nxt]) continue; f[nxt][0] = x; d[nxt] = d[x] + 1; for(int j = 1; j <= tt; j++){ f[nxt][j] = f[f[nxt][j - 1]][j - 1]; } q1.push(nxt); } } } int gettop(int x, int R){ int now = x; for(int i = tt; i >= 0; i--){ if(t[f[now][i]] <= R && f[now][i]){ now = f[now][i]; } } return now; } void dfs1(int now, int fa){ in[now] = ++cnt; id[cnt] = now; for(auto x : G[now]){ if(x == fa) continue; dfs1(x, now); } out[now] = cnt; }
signed main(void) { n = read(); for(int i = 1; i <= n - 1; i++){ int u = read(), v = read(); G[u].push_back(v), G[v].push_back(u); } for(int i = 1; i <= n; i++) t[i] = read(); pre(1); dfs1(1, 0); for(int i = 1; i <= n; i++) dfnt[i] = t[id[i]]; mt.Build(1, 1, n, dfnt); q = read(); for(int i = 1; i <= q; i++) { int x = read(), l = read(), r = read(); if(!(t[x] >= l && t[x] <= r)) { printf("%lld\n", 0LL); continue; } int subrt = gettop(x, r); printf("%lld\n", mt.Query(1, in[subrt], out[subrt], l)); } return 0; }
|