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. 微型 Python Web 框架: Bottle

    微型 Python Web 框架: Bottle 在 19/09/11 07:04 PM 由 COSTONY 发表 Bottle 是一个非常小巧但高效的微型 Python Web 框架,它被设计为仅仅 ...

  2. fir分布式滤波的fpga实现

    此设计的结构包括:1.移位寄存器链,n阶的有n-1个寄存器. 2.第一次累加部分.由fir滤波系数对称可得到对称的寄存器相加可以减小电路规模,所以第一次累加很有必要. 3,锁存并移位部分.此部分是为了 ...

  3. jquery移除、绑定、触发元素事件

    unbind(type [,data]) //data是要移除的函数 $('#btn').unbind("click"); //移除click $('#btn').unbind() ...

  4. 提升Apache网站访问速度的优化方法

    Apache是世界使用排名第一的Web服务器软件.它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一. 在Apache服务器上怎样优化才能提高 ...

  5. php单链表实现

    php单链表实现 <?php //单链表 class Hero{ public $no; public $name; public $nickname; public $next=null; f ...

  6. HDOJ5876(补图的最短路)

    Sparse Graph Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)To ...

  7. PL/Sql developer安装,设置

    安装PL/Sql developer,和安装出现错误(oracle client not properly installed),pl/sql中文乱码 下载安装plsql_dev(文末有64位的百度云 ...

  8. npm国内镜像介绍

    这个也是网上搜的,亲自试过,非常好用! 镜像使用方法(三种办法任意一种都能解决问题,建议使用第三种,将配置写死,下次用的时候配置还在): 1.通过config命令 npm config set reg ...

  9. 终端启动tomcat报错 command not found 解决方法 (含启动和关闭命令)

    Tomcat配置步骤: 1.cd命令进入Tomcat安装路径的bin下 2.sudo chmod 755*.sh 输入appleID密码获得相关权限 3.sudo sh ./startup.sh启动T ...

  10. java图形化界面-------鼠标监听画圆----------使用匿名类

    package com.aa; import java.awt.Color; import java.awt.Graphics; import java.awt.event.MouseAdapter; ...