码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ4003 [JLOI2015]城池攻占

时间:2015-04-22 21:59:29      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:

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

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

看从$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\n", ans1[i]);
142     for (i = 1; i <= m; ++i) printf("%d\n", ans2[i]);
143     return 0;
144 }
View Code

 

BZOJ4003 [JLOI2015]城池攻占

标签:

原文地址:http://www.cnblogs.com/rausen/p/4448741.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!