• 「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 }
  • 相关阅读:
    Vue之登录基础交互
    Vue之Slot用法初探
    序言
    sqlserver下通用 行转列 函数(原创)
    A printf format reference page (cheat sheet)
    [PowerShell]HTML parsing -- get information from a website
    [Python]打印a..z的字符
    Takari Extensions for Apache Maven (TEAM)
    【转】LAMBDAFICATOR: Crossing the gap from imperative to functional programming through refactorings
    [转][Java]使用Spring配合Junit进行单元测试的总结
  • 原文地址:https://www.cnblogs.com/WuliWuliiii/p/13769565.html
Copyright © 2020-2023  润新知