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

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

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

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

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

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

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

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

 /**************************************************************
Problem: 4003
User: rausen
Language: C++
Result: Accepted
Time:6872 ms
Memory:56988 kb
****************************************************************/ #include <cstdio>
#include <cmath>
#include <algorithm> using namespace std;
typedef double lf;
typedef long long ll; const int N = 3e5 + ; struct edge {
int next, to;
edge(int _n = , int _t = ) : next(_n), to(_t) {}
} e[N]; struct heap {
heap *ls, *rs;
ll v, tag_t, tag_a;
int dep, st, w; void* operator new(size_t, int x, int y, ll z) {
static heap mempool[N], *c = mempool;
c -> ls = c -> rs = NULL;
c -> dep = , c -> v = z, c -> w = x, c -> st = y;
c -> tag_t = , c -> tag_a = ;
return c++;
} inline void Times(ll x) {
v *= x, tag_t *= x, tag_a *= x;
}
inline void Add(ll x) {
v += x, tag_a += x;
}
inline void push() {
if (ls) ls -> Times(tag_t);
if (rs) rs -> Times(tag_t);
tag_t = ;
if (ls) ls -> Add(tag_a);
if (rs) rs -> Add(tag_a);
tag_a = ;
} #define Dep(p) (p ? p -> dep : 0)
inline void update() {
dep = Dep(rs) + ;
} friend heap* merge(heap *x, heap *y) {
if (!x) return y;
if (!y) return x;
if (x -> v > y -> v) swap(x, y);
x -> push();
x -> rs = merge(x -> rs, y);
if (Dep(x -> rs) > Dep(x -> ls)) swap(x -> ls, x -> rs);
x -> update();
return x;
}
#undef Dep inline heap* pop() {
this -> push();
return merge(ls, rs);
}
} *h[N]; struct tree_node {
int fa, a, dep;
ll h, v;
} tr[N]; inline ll read() {
static ll x, sgn;
static char ch;
x = , sgn = , ch = getchar();
while (ch < '' || '' < ch) {
if (ch == '-') sgn = -;
ch = getchar();
}
while ('' <= ch && ch <= '') {
x = x * + ch - '';
ch = getchar();
}
return sgn * x;
} int n, m;
int first[N], tot;
int ans1[N], ans2[N]; inline void add_edge(int x, int y) {
e[++tot] = edge(first[x], y);
first[x] = tot;
} #define y e[x].to
void dfs(int p) {
int x;
tr[p].dep = tr[tr[p].fa].dep + ;
for (x = first[p]; x; x = e[x].next) {
dfs(y);
h[p] = merge(h[p], h[y]);
}
while (h[p] && h[p] -> v < tr[p].h) {
++ans1[p], ans2[h[p] -> w] = tr[h[p] -> st].dep - tr[p].dep;
h[p] = h[p] -> pop();
}
if (h[p])
if (tr[p].a) h[p] -> Times(tr[p].v);
else h[p] -> Add(tr[p].v);
}
#undef y int main() {
int i, x, c;
ll s;
n = read(), m = read();
for (i = ; i <= n; ++i) tr[i].h = read();
for (i = ; i <= n; ++i) {
x = read(), add_edge(x, i);
tr[i].fa = x , tr[i].a = read(), tr[i].v = read();
}
for (i = ; i <= m; ++i) {
s = read(), c = read();
h[c] = merge(h[c], new(i, c, s)heap);
}
dfs();
while (h[]) {
ans2[h[] -> w] = tr[h[] -> st].dep;
h[] = h[] -> pop();
}
for (i = ; i <= n; ++i) printf("%d\n", ans1[i]);
for (i = ; i <= m; ++i) printf("%d\n", ans2[i]);
return ;
}

BZOJ4003 [JLOI2015]城池攻占的更多相关文章

  1. [bzoj4003][JLOI2015]城池攻占_左偏树

    城池攻占 bzoj-4003 JLOI-2015 题目大意:一颗n个节点的有根数,m个有初始战斗力的骑士都站在节点上.每一个节点有一个standard,如果这个骑士的战斗力超过了这个门槛,他就会根据城 ...

  2. BZOJ4003 [JLOI2015]城池攻占 左偏树 可并堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4003 题意概括 题意有点复杂,直接放原题了. 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑 ...

  3. BZOJ4003[JLOI2015]城池攻占——可并堆

    题目描述 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖, 其中 fi ...

  4. [BZOJ4003][JLOI2015]城池攻占(左偏树)

    这题有多种做法,一种是倍增预处理出每个点往上走2^i步最少需要的初始战斗力,一种是裸的启发式合并带标记splay. 每个点合并能攻占其儿子的所有骑士,删去所有无法攻占这个城市的骑士并记录答案. 注意到 ...

  5. BZOJ4003 JLOI2015城池攻占

    用左偏树模拟攻占的过程,维护最小值,最多入和出m次,每次log复杂度. #include<bits/stdc++.h> using namespace std; ; typedef lon ...

  6. 【BZOJ4003】[JLOI2015]城池攻占 可并堆

    [BZOJ4003][JLOI2015]城池攻占 Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号 ...

  7. BZOJ_4003_[JLOI2015]城池攻占_可并堆

    BZOJ_4003_[JLOI2015]城池攻占_可并堆 Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 ...

  8. [洛谷P3261] [JLOI2015]城池攻占(左偏树)

    不得不说,这道题目是真的难,真不愧它的“省选/NOI-”的紫色大火题!!! 花了我晚自习前半节课看题解,写代码,又花了我半节晚自习调代码,真的心态爆炸.基本上改得和题解完全一样了我才过了这道题!真的烦 ...

  9. BZOJ4003:[JLOI2015]城池攻占——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4003 https://www.luogu.org/problemnew/show/P3261 小铭 ...

随机推荐

  1. Hibernate级联删除时:Cannot delete or update a parent row: a foreign key constraint fails异常

    在删除主表数据时,报了一个异常 Cannot delete or update a parent row: a foreign key constraint fails 原因是主表中还包含字表的数据, ...

  2. Java 实现二分法查找算法

    算法 假如有一组数为3,12,24,36,55,68,75,88要查给定的值24.可设三个变量front,mid,end分别指向数据的上界,中间和下界,mid=(front+end)/2. 1.开始令 ...

  3. jquery ajax 实例

    $(function(){ $.ajax( { url:'{:U('shenhe')}',// 跳转到 action data:{ }, type:'post', cache:false, dataT ...

  4. Mysql中的排序规则utf8_unicode_ci、utf8_general_ci的区别总结

    Mysql中utf8_general_ci与utf8_unicode_ci有什么区别呢?在编程语言中,通常用unicode对中文字符做处理,防止出现乱码,那么在MySQL里,为什么大家都使用utf8_ ...

  5. CentOS查看CPU、内存、网络流量和磁盘 I/O【转载,待整理】

    http://blog.csdn.net/zbyufei/article/details/6413273

  6. 转:如何学习SQL(第三部分:SQL数据类型与三值逻辑)

    转自:http://blog.163.com/mig3719@126/blog/static/285720652010950921286/ 7. 数据类型 在数据库理论中,关系模型和数据类型这两部分内 ...

  7. D3.js 第一个程序 HelloWorld

    一.HTML 是怎么输出 HelloWorld 的 <html> <head> <meta charset="utf-8"> <title ...

  8. OpenGL的gluPerspective透视投影变换函数详解[转]

    函数原型void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) 首先得设置gluPersp ...

  9. [转载]最牛B的编码套路

    原文地址:http://www.codeceo.com/article/nb-coding-style.html 这篇文章很不错,推荐给大家看. 最近,我大量阅读了Steve Yegge的文章.其中有 ...

  10. er6855的工作经验

    1 VIEWS里面的关系要搞清楚 里面的内容类型要理清 不要相信别人做好的事情 不要相信看到的结果 2 git rm -rf之后需要git commit提交到.git文件中正式生效 不然可能就是中间打 ...