• BZOJ4003 [JLOI2015]城池攻占


    这题有两种做法来着。。。

    第一种就是一开始想到的比较不靠谱,不过貌似可以过掉:

    看从$1$号节点开始到$p$号节点最大需要的体力,记录单调上升的体力,询问的时候二分跳着走就可以了

    不过精度问题还有可能爆double什么的QAQ

    于是写了一半果断弃疗。。。结果有人说他过了【摔

    第二种是正解,对于每个点我们可以先把下面的骑士都先做完然后还活着的全部搞到这个点上来,然后再看有谁死在这个点上了

    所以我们要维护能都删除/查询最小值,合并,允许打标记的数据结构

    貌似是可并堆喵!【完结撒花~

      1 /**************************************************************
      2     Problem: 4003
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:6872 ms
      7     Memory:56988 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cmath>
     12 #include <algorithm>
     13  
     14 using namespace std;
     15 typedef double lf;
     16 typedef long long ll;
     17  
     18 const int N = 3e5 + 5;
     19  
     20 struct edge {
     21     int next, to;
     22     edge(int _n = 0, int _t = 0) : next(_n), to(_t) {}
     23 } e[N];
     24  
     25 struct heap {
     26     heap *ls, *rs;
     27     ll v, tag_t, tag_a;
     28     int dep, st, w;
     29      
     30     void* operator new(size_t, int x, int y, ll z) {
     31         static heap mempool[N], *c = mempool;
     32         c -> ls = c -> rs = NULL;
     33         c -> dep = 1, c -> v = z, c -> w = x, c -> st = y;
     34         c -> tag_t = 1, c -> tag_a = 0;
     35         return c++;
     36     }
     37      
     38     inline void Times(ll x) {
     39         v *= x, tag_t *= x, tag_a *= x;
     40     }   
     41     inline void Add(ll x) {
     42         v += x, tag_a += x;
     43     }   
     44     inline void push() {
     45         if (ls) ls -> Times(tag_t);
     46         if (rs) rs -> Times(tag_t);
     47         tag_t = 1;
     48         if (ls) ls -> Add(tag_a);
     49         if (rs) rs -> Add(tag_a);
     50         tag_a = 0;
     51     }
     52      
     53     #define Dep(p) (p ? p -> dep : 0)
     54     inline void update() {
     55         dep = Dep(rs) + 1;
     56     }
     57          
     58     friend heap* merge(heap *x, heap *y) {
     59         if (!x) return y;
     60         if (!y) return x;
     61         if (x -> v > y -> v) swap(x, y);
     62         x -> push();
     63         x -> rs = merge(x -> rs, y);
     64         if (Dep(x -> rs) > Dep(x -> ls)) swap(x -> ls, x -> rs);
     65         x -> update();
     66         return x;
     67     }
     68     #undef Dep
     69      
     70     inline heap* pop() {
     71         this -> push();
     72         return merge(ls, rs);
     73     }
     74 } *h[N];
     75  
     76 struct tree_node {
     77     int fa, a, dep;
     78     ll h, v;
     79 } tr[N];
     80  
     81 inline ll read() {
     82     static ll x, sgn;
     83     static char ch;
     84     x = 0, sgn = 1, ch = getchar();
     85     while (ch < '0' || '9' < ch) {
     86         if (ch == '-') sgn = -1;
     87         ch = getchar();
     88     }
     89     while ('0' <= ch && ch <= '9') {
     90         x = x * 10 + ch - '0';
     91         ch = getchar();
     92     }
     93     return sgn * x;
     94 }
     95  
     96 int n, m;
     97 int first[N], tot;
     98 int ans1[N], ans2[N];
     99  
    100 inline void add_edge(int x, int y) {
    101     e[++tot] = edge(first[x], y);
    102     first[x] = tot;
    103 }
    104  
    105 #define y e[x].to
    106 void dfs(int p) {
    107     int x;
    108     tr[p].dep = tr[tr[p].fa].dep + 1;
    109     for (x = first[p]; x; x = e[x].next) {
    110         dfs(y);
    111         h[p] = merge(h[p], h[y]);
    112     }
    113     while (h[p] && h[p] -> v < tr[p].h) {
    114         ++ans1[p], ans2[h[p] -> w] = tr[h[p] -> st].dep - tr[p].dep;
    115         h[p] = h[p] -> pop();
    116     }
    117     if (h[p])
    118         if (tr[p].a) h[p] -> Times(tr[p].v);
    119         else h[p] -> Add(tr[p].v);
    120 }
    121 #undef y
    122  
    123 int main() {
    124     int i, x, c;
    125     ll s;
    126     n = read(), m = read();
    127     for (i = 1; i <= n; ++i) tr[i].h = read();
    128     for (i = 2; i <= n; ++i) {
    129         x = read(), add_edge(x, i);
    130         tr[i].fa = x    , tr[i].a = read(), tr[i].v = read();
    131     }
    132     for (i = 1; i <= m; ++i) {
    133         s = read(), c = read();
    134         h[c] = merge(h[c], new(i, c, s)heap);
    135     }
    136     dfs(1);
    137     while (h[1]) {
    138         ans2[h[1] -> w] = tr[h[1] -> st].dep;
    139         h[1] = h[1] -> pop();
    140     }
    141     for (i = 1; i <= n; ++i) printf("%d
    ", ans1[i]);
    142     for (i = 1; i <= m; ++i) printf("%d
    ", ans2[i]);
    143     return 0;
    144 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    eclipse
    ORA00904:标识符无效,preparedstatement
    mysql 创建用户
    web 默认servlet
    https tomat
    gzip
    sftp 上传文件
    jquery dwrutil confilit
    xmlbeans读写xml文件
    敏捷开发“松结对编程”实践大型团队篇
  • 原文地址:https://www.cnblogs.com/rausen/p/4448741.html
Copyright © 2020-2023  润新知