• 左偏树初步 bzoj2809 & bzoj4003


      看着百度文库学习了一个。

      总的来说,左偏树这个可并堆满足 堆的性质 和 左偏 性质。

      bzoj2809: [Apio2012]dispatching

        把每个忍者先放到节点上,然后从下往上合并,假设到了这个点 总值 大于 预算,那么我们把这个 大根堆 的堆顶弹掉就好了,剩下的就是可合并堆。

        感谢prey :)

        

     1 #include <bits/stdc++.h>
     2 #define rep(i, a, b) for (int i = a; i <= b; i++)
     3 #define drep(i, a, b) for (int i = a; i >= b; i--)
     4 #define REP(i, a, b) for (int i = a; i < b; i++)
     5 #define mp make_pair
     6 #define pb push_back
     7 #define clr(x) memset(x, 0, sizeof(x))
     8 #define xx first
     9 #define yy second
    10 using namespace std;
    11 typedef pair<int, int> pii;
    12 typedef long long ll;
    13 const int inf = 0x3f3f3f3f;
    14 const ll INF = 0x3f3f3f3f3f3f3f3fll;
    15 //************************************************
    16  
    17 const int maxn = 100005;
    18  
    19 struct Ed {
    20     int u, v, nx; Ed() {}
    21     Ed(int _u, int _v, int _nx) :
    22         u(_u), v(_v), nx(_nx) {}
    23 } E[maxn];
    24 int G[maxn], edtot;
    25 void addedge(int u, int v) {
    26     E[++edtot] = Ed(u, v, G[u]);
    27     G[u] = edtot;
    28 }
    29  
    30 int pre[maxn], C[maxn], L[maxn], son[maxn];
    31 struct node {
    32     int key, dis, l, r, sz;
    33 } heap[maxn];
    34 int ndtot;
    35  
    36 int root[maxn];
    37 ll M;
    38 template <typename T> inline void MaxT (T &a, const T b) { if (a < b) a = b; }
    39 ll ans = -1;
    40 int merge(int x, int y) {
    41     if (!x) return y;
    42     if (!y) return x;
    43     if (heap[x].key < heap[y].key) swap(x, y);
    44     heap[x].r = merge(heap[x].r, y);
    45     heap[x].sz = heap[heap[x].l].sz + heap[heap[x].r].sz + 1;
    46     if (heap[heap[x].l].dis < heap[heap[x].r].dis) swap(heap[x].l, heap[x].r);
    47     heap[x].dis = heap[heap[x].r].dis + 1;
    48     return x;
    49 }
    50 ll solve(int x) {
    51     ll sum = C[x];
    52     heap[root[x] = ++ndtot] = (node) {C[x], 0, 0, 0, 1};
    53     for (int i = G[x], y; i; i = E[i].nx) {
    54         sum += solve(y = E[i].v);
    55         root[x] = merge(root[x], root[y]);
    56     }
    57     while (sum > M) sum -= heap[root[x]].key, root[x] = merge(heap[root[x]].l, heap[root[x]].r);
    58     MaxT(ans, 1ll * heap[root[x]].sz * L[x]);
    59     return sum;
    60 }
    61  
    62 int main() {
    63     int n; scanf("%d%lld", &n, &M);
    64     int rt;
    65     rep(i, 1, n) {
    66         scanf("%d%d%d", pre + i, C + i, L + i);
    67         son[pre[i]]++;
    68         if (pre[i] == 0) rt = i;
    69         addedge(pre[i], i);
    70     }
    71     solve(rt);
    72     printf("%lld
    ", ans);
    73     return 0;
    74 }
    View Code

      bzoj4003: [JLOI2015]城池攻占

        堆上打个lazytag即可,可以表示成 tag_a * x + tag_b 的形式,标记的合并也很简单,tag_a2 * (tag_a1 * x + tag_b1) + tag_b2,乘开就好。

      1 #include <bits/stdc++.h>
      2 #define rep(i, a, b) for (int i = a; i <= b; i++)
      3 #define drep(i, a, b) for (int i = a; i >= b; i--)
      4 #define REP(i, a, b) for (int i = a; i < b; i++)
      5 #define mp make_pair
      6 #define pb push_back
      7 #define clr(x) memset(x, 0, sizeof(x))
      8 #define xx first
      9 #define yy second
     10 using namespace std;
     11 typedef pair<int, int> pii;
     12 typedef long long ll;
     13 const int inf = 0x3f3f3f3f;
     14 const ll INF = 0x3f3f3f3f3f3f3f3fll;
     15 //************************************************
     16  
     17 const int maxn = 300005;
     18  
     19 struct Ed {
     20     int u, v, nx; Ed() {}
     21     Ed(int _u, int _v, int _nx) :
     22         u(_u), v(_v), nx(_nx) {}
     23 } E[maxn];
     24 int G[maxn], edtot;
     25 void addedge(int u, int v) {
     26     E[++edtot] = Ed(u, v, G[u]);
     27     G[u] = edtot;
     28 }
     29  
     30 struct node {
     31     int dis, l, r, sz;
     32     ll key, tag_a, tag_b;
     33     int id;
     34 } heap[maxn];
     35 int ndtot;
     36  
     37 ll hp[maxn], A[maxn], V[maxn];
     38 int pre[maxn], root[maxn];
     39 ll S[maxn], C[maxn];
     40  
     41 void Push_down(int x) {
     42     if (heap[x].tag_a == 1 && heap[x].tag_b == 0) return;
     43     int l = heap[x].l, r = heap[x].r;
     44     heap[l].tag_a *= heap[x].tag_a, heap[l].tag_b = heap[l].tag_b * heap[x].tag_a + heap[x].tag_b;
     45     heap[r].tag_a *= heap[x].tag_a, heap[r].tag_b = heap[r].tag_b * heap[x].tag_a + heap[x].tag_b;
     46     heap[l].key = heap[l].key * heap[x].tag_a + heap[x].tag_b;
     47     heap[r].key = heap[r].key * heap[x].tag_a + heap[x].tag_b;
     48     heap[x].tag_a = 1, heap[x].tag_b = 0;
     49     return;
     50 }
     51  
     52 int merge(int x, int y) {
     53     if (!x) return y;
     54     if (!y) return x;
     55     Push_down(x), Push_down(y);
     56     if (heap[x].key > heap[y].key) swap(x, y);
     57     heap[x].r = merge(heap[x].r, y);
     58     heap[x].sz = heap[heap[x].l].sz + heap[heap[x].r].sz + 1;
     59     if (heap[heap[x].l].dis < heap[heap[x].r].dis) swap(heap[x].l, heap[x].r);
     60     heap[x].dis = heap[heap[x].r].dis + 1;
     61     return x;
     62 }
     63  
     64 int Stop[maxn], Peo[maxn];
     65 int dep[maxn];
     66 void solve(int x) {
     67     for (int i = G[x], y; i; i = E[i].nx) {
     68         dep[y = E[i].v] = dep[x] + 1;
     69         solve(y);
     70         root[x] = merge(root[x], root[y]);
     71     }
     72     Push_down(root[x]);
     73     while (root[x] && heap[root[x]].key < hp[x]) {
     74         Push_down(root[x]);
     75         Stop[heap[root[x]].id] = x;
     76         Peo[x]++;
     77         root[x] = merge(heap[root[x]].l, heap[root[x]].r);
     78     }
     79     if (root[x]) {
     80         Push_down(root[x]);
     81         if (A[x] == 0) heap[root[x]].tag_b = V[x], heap[root[x]].key += V[x];
     82         else heap[root[x]].tag_a = V[x], heap[root[x]].key *= V[x];
     83     }
     84 }
     85  
     86 int main() {
     87     int n, m; scanf("%d%d", &n, &m);
     88     rep(i, 1, n) scanf("%lld", hp + i);
     89     rep(i, 2, n) {
     90         scanf("%d%lld%lld", pre + i, A + i, V + i);
     91         addedge(pre[i], i);
     92     }
     93     rep(i, 1, m) {
     94         scanf("%lld%lld", S + i, C + i);
     95         heap[++ndtot] = (node) {0, 0, 0, 1, S[i], 1, 0, i};
     96         root[C[i]] = merge(root[C[i]], ndtot);
     97     }
     98     solve(1);
     99     rep(i, 1, n) printf("%d
    ", Peo[i]);
    100     rep(i, 1, m) printf("%d
    ", Stop[i] ? dep[C[i]] - dep[Stop[i]] : dep[C[i]] + 1);
    101 }
    View Code
  • 相关阅读:
    phpstorm+Xdebug断点调试PHP
    解决PHP curl https时error 77(Problem with reading the SSL CA cert (path? access rights?))
    Windows下安装并设置Redis
    PHP使用数据库的并发问题
    PHP 数组排序
    js 异常处理
    nginx php上传大文件的设置(php-fpm)
    第二章 基本数据类型:常见数据类型的方法
    第一章 python介绍、变量、数据类型、流程控制语句等
    python2.x和python3.x的区别
  • 原文地址:https://www.cnblogs.com/y7070/p/5183777.html
Copyright © 2020-2023  润新知