我们可以对树上的每个点维护一个左偏树,维护的是在该点上的骑士的数量,以及他们的信息,他们的信息指的是他们的战斗力的值,此时还需要推一个lazy,对整个堆去推这个lazy即可。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <string> 5 #include <cstring> 6 #include <algorithm> 7 #include <limits> 8 #include <vector> 9 #include <stack> 10 #include <queue> 11 #include <set> 12 #include <map> 13 #include <bitset> 14 #include <unordered_map> 15 #include <unordered_set> 16 #define lowbit(x) ( x&(-x) ) 17 #define pi 3.141592653589793 18 #define e 2.718281828459045 19 #define INF 0x3f3f3f3f 20 #define HalF (l + r)>>1 21 #define lsn rt<<1 22 #define rsn rt<<1|1 23 #define Lson lsn, l, mid 24 #define Rson rsn, mid+1, r 25 #define QL Lson, ql, qr 26 #define QR Rson, ql, qr 27 #define myself rt, l, r 28 #define pii pair<int, int> 29 #define MP(a, b) make_pair(a, b) 30 #define lc t[x].c[0] 31 #define rc t[x].c[1] 32 using namespace std; 33 typedef unsigned long long ull; 34 typedef unsigned int uit; 35 typedef long long ll; 36 const int maxN = 3e5 + 7; 37 int N, M, a[maxN], c[maxN], deep[maxN], root[maxN], tot, died[maxN] = {0}, sum[maxN] = {0}; 38 ll h[maxN], v[maxN], s[maxN]; 39 struct node 40 { 41 ll val, lazy_add, lazy_mul; int d, c[2], fa; 42 node(ll a=0, int b=0, int c1=0, int c2=0, int f=0):val(a), d(b), c{c1, c2}, fa(f) { lazy_add = 0; lazy_mul = 1; } 43 } t[maxN]; 44 int fid(int x) { return x == t[x].fa ? x : t[x].fa = fid(t[x].fa); } 45 void pushdown(int x) 46 { 47 if(t[x].lazy_add || t[x].lazy_mul != 1) 48 { 49 t[lc].val = t[lc].val * t[x].lazy_mul + t[x].lazy_add; 50 t[rc].val = t[rc].val * t[x].lazy_mul + t[x].lazy_add; 51 t[lc].lazy_add = t[lc].lazy_add * t[x].lazy_mul + t[x].lazy_add; 52 t[rc].lazy_add = t[rc].lazy_add * t[x].lazy_mul + t[x].lazy_add; 53 t[lc].lazy_mul *= t[x].lazy_mul; 54 t[rc].lazy_mul *= t[x].lazy_mul; 55 t[x].lazy_add = 0; 56 t[x].lazy_mul = 1; 57 } 58 } 59 int Merge(int x, int y) 60 { 61 if(!x || !y) return x | y; 62 if(t[x].val > t[y].val) swap(x, y); 63 pushdown(x); 64 t[x].c[1] = Merge(t[x].c[1], y); 65 t[t[x].c[1]].fa = x; 66 if(t[t[x].c[0]].d < t[t[x].c[1]].d) swap(t[x].c[0], t[x].c[1]); 67 t[x].d = t[t[x].c[1]].d + 1; 68 return x; 69 } 70 void Pop(int x, int u) 71 { 72 int f = fid(x); 73 while(f && t[f].val < h[u]) 74 { 75 died[f] = u; 76 pushdown(f); 77 t[t[f].c[0]].fa = t[f].c[0]; 78 t[t[f].c[1]].fa = t[f].c[1]; 79 t[f].fa = Merge(t[f].c[0], t[f].c[1]); 80 t[f].c[0] = t[f].c[1] = 0; 81 root[u] = f = t[f].fa; 82 sum[u]++; 83 } 84 } 85 vector<int> to[maxN]; 86 void dfs(int u) 87 { 88 for(int v : to[u]) 89 { 90 deep[v] = deep[u] + 1; 91 dfs(v); 92 root[u] = Merge(root[u], root[v]); 93 } 94 Pop(root[u], u); 95 int f = fid(root[u]); 96 if(f) 97 { 98 if(a[u]) 99 { 100 t[f].lazy_add *= v[u]; 101 t[f].lazy_mul *= v[u]; 102 t[f].val *= v[u]; 103 } 104 else 105 { 106 t[f].lazy_add += v[u]; 107 t[f].val += v[u]; 108 } 109 } 110 } 111 int main() 112 { 113 scanf("%d%d", &N, &M); 114 for(int i=1; i<=N; i++) scanf("%lld", &h[i]); 115 for(int i=2, f; i<=N; i++) 116 { 117 scanf("%d%d%lld", &f, &a[i], &v[i]); 118 to[f].push_back(i); 119 } 120 for(int i=1; i<=M; i++) 121 { 122 scanf("%lld%d", &s[i], &c[i]); 123 t[i].val = s[i]; t[i].fa = i; 124 root[c[i]] = Merge(root[c[i]], i); 125 } 126 deep[0] = 0; 127 deep[1] = 1; 128 dfs(1); 129 for(int i=1; i<=N; i++) printf("%d\n", sum[i]); 130 for(int i=1; i<=M; i++) printf("%d\n", deep[c[i]] - deep[died[i]]); 131 return 0; 132 }