zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Construct Binary Tree from Preorder and Inorder Traversal
    Construct Binary Tree from Inorder and Postorder Traversal
    Maximum Depth of Binary Tree
    Sharepoint 2013 创建TimeJob 自动发送邮件
    IE8 不能够在Sharepoint平台上在线打开Office文档解决方案
    TFS安装与管理
    局域网通过IP查看对方计算机名,通过计算机名查看对方IP以及查看在线所有电脑IP
    JS 隐藏Sharepoint中List Item View页面的某一个字段
    SharePoint Calculated Column Formulas & Functions
    JS 两个一组数组转二维数组
  • 原文地址:https://www.cnblogs.com/rausen/p/4448741.html
Copyright © 2011-2022 走看看