「JLOI2015」城池攻占【左偏树】

题目链接LOJ-2107

  我们可以对树上的每个点维护一个左偏树,维护的是在该点上的骑士的数量,以及他们的信息,他们的信息指的是他们的战斗力的值,此时还需要推一个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
", sum[i]);
130     for(int i=1; i<=M; i++) printf("%d
", deep[c[i]] - deep[died[i]]);
131     return 0;
132 }
原文地址:https://www.cnblogs.com/WuliWuliiii/p/13769565.html