BZOJ 4003

需要实现一个可并堆。

每个点维护一个小根堆,然后一开始把所有骑士加入到它所在的点的小根堆当中,实际上空间是$O(m)$的,然后我们从上到下不断合并这个小根堆,合并完之后如果遇到堆顶小于当前城市的防御值就弹掉堆顶顺便记录答案。

对于那些攻占掉城池对骑士的贡献的处理,可以采用打标记的方式实现,在合并的时候$down$一下就好了。注意$down$要写在$merge$函数的最上面,因为有一些点还没有下传标记就被$merge$掉了。

要注意弹出堆顶元素之前要先$down$一下 。

最后在清空一下第一个堆中的元素就好了。

不会算时间复杂度$QωQ$。

Code:

// luogu-judger-enable-o2
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll; const int N = 3e5 + ; int n, m, tot = , head[N], type[N], dep[N], ans[N];
ll def[N], rat[N]; struct Knight {
int pos, ed;
ll atk;
} a[N]; struct Edge {
int to, nxt;
} e[N << ]; inline void add(int from, int to) {
e[++tot].to = to;
e[tot].nxt = head[from];
head[from] = tot;
} template <typename T>
inline void read(T &X) {
X = ; char ch = ; T op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} template <typename T>
inline void swap(T &x, T &y) {
T t = x; x = y; y = t;
} namespace LeftlistTree {
struct Node {
int lc, rc, dis, id;
ll key, mulTag, addTag;
} s[N]; #define lc(p) s[p].lc
#define rc(p) s[p].rc
#define key(p) s[p].key
#define mulTag(p) s[p].mulTag
#define addTag(p) s[p].addTag
#define dis(p) s[p].dis
#define id(p) s[p].id int root[N], nodeCnt = ; inline int newNode(int p) {
++nodeCnt;
lc(nodeCnt) = rc(nodeCnt) = ;
dis(nodeCnt) = ;
id(nodeCnt) = p;
key(nodeCnt) = a[p].atk;
addTag(nodeCnt) = 0LL, mulTag(nodeCnt) = 1LL;
return nodeCnt;
} inline void down(int p) {
if(!p) return;
if(mulTag(p) != ) {
if(lc(p)) {
key(lc(p)) *= mulTag(p);
addTag(lc(p)) *= mulTag(p);
mulTag(lc(p)) *= mulTag(p);
} if(rc(p)) {
key(rc(p)) *= mulTag(p);
addTag(rc(p)) *= mulTag(p);
mulTag(rc(p)) *= mulTag(p);
} mulTag(p) = ;
} if(addTag(p) != ) {
if(lc(p)) {
key(lc(p)) += addTag(p);
addTag(lc(p)) += addTag(p);
} if(rc(p)) {
key(rc(p)) += addTag(p);
addTag(rc(p)) += addTag(p);
} addTag(p) = ;
}
} int merge(int x, int y) {
down(x), down(y);
if(!x || !y) return x + y;
if(key(x) > key(y)) swap(x, y);
rc(x) = merge(rc(x), y); if(dis(lc(x)) < dis(rc(x))) swap(lc(x), rc(x));
dis(x) = dis(rc(x)) + ;
return x;
} } using namespace LeftlistTree; void solve(int x, int fat, int depth) {
dep[x] = depth;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(y == fat) continue;
solve(y, x, depth + ); root[x] = merge(root[x], root[y]);
} for(; root[x] && key(root[x]) < def[x]; ) {
++ans[x];
a[id(root[x])].ed = x;
down(root[x]);
root[x] = merge(lc(root[x]), rc(root[x]));
} if(root[x]) {
if(!type[x]) {
key(root[x]) += rat[x];
addTag(root[x]) += rat[x];
} else {
key(root[x]) *= rat[x];
mulTag(root[x]) *= rat[x];
addTag(root[x]) *= rat[x];
}
}
} int main() {
// freopen("3.in", "r", stdin);
// freopen("my.out", "w", stdout); read(n), read(m);
for(int i = ; i <= n; i++) read(def[i]);
for(int fat, i = ; i <= n; i++) {
read(fat);
add(fat, i), add(i, fat);
read(type[i]), read(rat[i]);
}
for(int i = ; i <= m; i++) {
read(a[i].atk), read(a[i].pos);
root[a[i].pos] = merge(root[a[i].pos], newNode(i));
} solve(, , ); for(int i = ; i <= n; i++)
printf("%d\n", ans[i]); for(; root[]; ) {
a[id(root[])].ed = ;
down(root[]);
root[] = merge(lc(root[]), rc(root[]));
} for(int i = ; i <= m; i++)
printf("%d\n", dep[a[i].pos] - dep[a[i].ed]); return ;
}

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

  1. BZOJ 4003 / Luogu P3261 [JLOI2015]城池攻占 (左偏树)

    左偏树裸题,在树上合并儿子传上来的堆,然后小于当前结点防御值的就pop掉,pop的时候统计答案. 修改的话就像平衡树一样打懒标记就行了. 具体见代码 CODE #include<bits/std ...

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

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

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

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

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

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

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

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

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

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

  7. [JLOI2015]城池攻占

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

  8. [JLOI2015]城池攻占 左偏树

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

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

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

随机推荐

  1. net core集成CAP

    net core集成CAP https://www.cnblogs.com/guolianyu/p/9756941.html 一.前言 感谢杨晓东大佬为社区贡献的CAP开源项目,传送门在此:.NET ...

  2. UIImage+PYJColorBecomeImage

    UIImage+PYJColorBecomeImage.h: // // UIImage+PYJColorBecomeImage.h // 颜色转成图片 // // Created by PengYu ...

  3. 关于altera的fft核使用问题记录

    altera的fft核使用比较特别,今天我做了一下仿真,发现一些问题,现做记录如下: 1,ip配置 parameters选项卡主要是fft变换的长度和数据长度,旋转因子长度,需要注意的是“Twiddl ...

  4. Spring按名称自动装配--byName

    在Spring中,“按名称自动装配”是指,如果一个bean的名称与其他bean属性的名称是一样的,那么将自动装配它. 例如,如果“customer” bean公开一个“address”属性,Sprin ...

  5. 老齐python-基础1

    1.基本对象类型     1.1数: >>> 3 #基本数字 3 >>> 3333 3333 >>> 3.222 3.222 >>&g ...

  6. nginx学习资源

    在了解nginx的时候 看到的一些资源: https://www.cnblogs.com/EdwinChan/p/8350984.html http://tengine.taobao.org/book ...

  7. 配置和启动脚本(bash shell学习01)

    bash是 Bourne Again Shell简称 ,从unix系统的sh发展而来 查看当前shellecho $SHELL查看系统支持的shellcat /etc/shells cd /binls ...

  8. 在Linux 64位系统下使用hugepage

    首先,为什么要介绍/使用HugePage? 在步入正题之前,先讲一个非常普遍的数据库性能问题. 众所周知,Oracle数据库使用共享内存(SGA)来管理可以共享的一些资源;比如shared pool中 ...

  9. 地下迷宫探索(dfs)

    地下迷宫探索(30 分) 地道战是在抗日战争时期,在华北平原上抗日军民利用地道打击日本侵略者的作战方式.地道网是房连房.街连街.村连村的地下工事,如下图所示. 我们在回顾前辈们艰苦卓绝的战争生活的同时 ...

  10. python selenium中iframe切换、window切换方法

    一.selenium中iframe切换方法: 方法一:switch_to.frame frame函数中提供了三种定位方法:by index, name, or webelement. driver.s ...