「JLOI2015」城池攻占 可并堆
分析
如果直接暴力枚举的话肯定会超时
我们可以从下往上遍历,维护一个小根堆
每次到达一个节点把战败的骑士扔出去
剩下的再继续向上合并,注意要维护一下其实的战斗力
可以像线段树那样用一个lazy标记
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=300005;
typedef long long ll;
ll head[maxn],tot=1;
struct asd{
ll from,to,next,ty;
ll val;
}b[maxn];
void ad(ll aa,ll bb,ll cc,ll dd){
b[tot].from=aa;
b[tot].to=bb;
b[tot].ty=cc;
b[tot].val=dd;
b[tot].next=head[aa];
head[aa]=tot++;
}
ll bjc[maxn],bjj[maxn],gjl[maxn];
ll lch[maxn],rch[maxn];
void push_down(ll xx){
if(xx==0) return;
if(bjc[xx]!=1){
gjl[lch[xx]]*=bjc[xx],bjj[lch[xx]]*=bjc[xx],bjc[lch[xx]]*=bjc[xx];
gjl[rch[xx]]*=bjc[xx],bjj[rch[xx]]*=bjc[xx],bjc[rch[xx]]*=bjc[xx];
bjc[xx]=1;
}
if(bjj[xx]!=0){
gjl[lch[xx]]+=bjj[xx],bjj[lch[xx]]+=bjj[xx];
gjl[rch[xx]]+=bjj[xx],bjj[rch[xx]]+=bjj[xx];
bjj[xx]=0;
}
}
ll d[maxn],dep[maxn],rt[maxn];
ll h[maxn];
ll bing(ll xx,ll yy){
if(!xx) return yy;
if(!yy) return xx;
push_down(xx),push_down(yy);
if(gjl[xx]>gjl[yy]) swap(xx,yy);
rch[xx]=bing(rch[xx],yy);
if(d[lch[xx]]<d[rch[xx]]) swap(lch[xx],rch[xx]);
d[xx]=d[rch[xx]]+1;
return xx;
}
ll killl[maxn],atk[maxn];
ll cnt=0;
void dfs(ll xx){
for(ll i=head[xx];i!=-1;i=b[i].next){
ll u=b[i].to;
dep[u]=dep[xx]+1,dfs(u);
if(b[i].ty) gjl[rt[u]]*=b[i].val,bjj[rt[u]]*=b[i].val,bjc[rt[u]]*=b[i].val;
else gjl[rt[u]]+=b[i].val,bjj[rt[u]]+=b[i].val;
rt[xx]=bing(rt[xx],rt[u]);
}
while(rt[xx] && gjl[rt[xx]]<h[xx]){
killl[xx]++,atk[rt[xx]]=xx,push_down(rt[xx]),rt[xx]=bing(lch[rt[xx]],rch[rt[xx]]);
}
}
ll jl[maxn];
int main(){
memset(head,-1,sizeof(head));
ll n,m;
scanf("%lld%lld",&n,&m);
for(ll i=1;i<=n;i++) scanf("%lld",&h[i]);
for(ll i=2;i<=n;i++){
ll aa;
ll bb,cc;
scanf("%lld%lld%lld",&aa,&bb,&cc);
ad(aa,i,bb,cc);
}
for(ll i=1;i<=m;i++){
bjc[i]=1;
ll bb;
scanf("%lld%lld",&gjl[i],&bb);
jl[i]=bb;
rt[bb]=bing(rt[bb],i);
}
d[0]=-1;
dep[1]=1;
dfs(1);
for(ll i=1;i<=n;i++) printf("%lld\n",killl[i]);
for(ll i=1;i<=n;i++) printf("%lld\n",dep[jl[i]]-dep[atk[i]]);
return 0;
}
「JLOI2015」城池攻占 可并堆的更多相关文章
- 「JLOI2015」城池攻占 解题报告
「JLOI2015」城池攻占 注意到任意两个人的战斗力相对大小的不变的 可以离线的把所有人赛到初始点的堆里 然后做启发式合并就可以了 Code: #include <cstdio> #in ...
- 【LOJ】#2107. 「JLOI2015」城池攻占
题解 用一个平衡树维护能攻占到u点的骑士,合并到父亲的时候去掉攻击力小于父亲生命值的那部分,只要把那棵树拆掉并且将树中的所有骑士更新一下答案,用无旋式treap很好写 合并的时候只要启发式合并就可以了 ...
- 「JLOI2015」骗我呢 解题报告?
「JLOI2015」骗我呢 这什么神仙题 \[\color{purple}{Link}\] 可以学到的东西 对越过直线的东西翻折进行容斥 之类的..吧? Code: #include <cstd ...
- 「JLOI2015」管道连接 解题报告
「JLOI2015」管道连接 先按照斯坦纳树求一个 然后合并成斯坦纳森林 直接枚举树的集合再dp一下就好了 Code: #include <cstdio> #include <cct ...
- 「JLOI2015」战争调度 解题报告
「JLOI2015」战争调度 感觉一到晚上大脑就宕机了... 题目本身不难,就算没接触过想想也是可以想到的 这个满二叉树的深度很浅啊,每个点只会和它的\(n-1\)个祖先匹配啊 于是可以暴力枚举祖先链 ...
- 【BZOJ4003】[JLOI2015]城池攻占 可并堆
[BZOJ4003][JLOI2015]城池攻占 Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号 ...
- 【BZOJ】【4003】【JLOI2015】城池攻占
可并堆 QAQ改了一下午……最终弃疗求助zyf……居然被秒了QAQ真是弱到不行(zyf太神了Orz) 还是先考虑部分分的做法: 1.$n,m\leq 3000$:可以暴力模拟每个骑士的攻打过程,也可以 ...
- BZOJ4003[JLOI2015]城池攻占——可并堆
题目描述 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖, 其中 fi ...
- BZOJ 4003 【JLOI2015】城池攻占
Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖, ...
随机推荐
- Linux笔记(第一天)
一.命令 lscpu -- 查看cpu free -- 内存查看 -m 以M ...
- 第二个hibernate Annotation版本的helloworld
经过第一次的 hibernate 我发现每一个数据库表都对应了一个类,并且每一个类都要新建一个文件进行配置 很麻烦! 于是便出现了Annotation版本的hibernate. 具体如下: 1.同 ...
- 如何优雅地停止 Spring Boot 应用?
首先来介绍下什么是优雅地停止,简而言之,就是对应用进程发送停止指令之后,能保证正在执行的业务操作不受影响,可以继续完成已有请求的处理,但是停止接受新请求. 在 Spring Boot 2.3 中增加了 ...
- Centos 文件系统基础命令
目录 centos7的目录结构(linux所以的都文件,万物接文件) 1 pwd 显示当前所在的路径 2 cd 切换目录结构 3 mkdir创建目录信息 4 touch 创建文件(触摸) 5 ls 检 ...
- 内核与驱动文件的version magic匹配问题
https://blog.csdn.net/yubing_615/article/details/52183185 1.问题:本地编译的一整套底层代码down到设备跑都正常,但是由这套代码上传SVN服 ...
- SQL常用取整函数
1.Round(column_name,decimals):用于把数值字段舍入为指定的小数位数 2.Floor(column_name): 向下取整,主要用于获得小于等于数值表达式的最大整数. 3.C ...
- Laravel:No application encryption key has been specified.
其实吧,这个就是你没有生成密钥 你首先去看看,如果是刚刚下载的lavavel应该会有一个.env.example文件在根目录下,然后修改这个文件名,改成.env 然后用命令行去执行php artisa ...
- Windows 程序设计(4) MFC 03 -系列学习
本文整体目录和绝大部门内容来自 [鸡啄米网站]的MFC系列文章,欢迎支持原创 (一)VS2010/MFC编程入门之前言 VC++全称是Visual C++,是由微软提供的C++开发工具,它与C++的根 ...
- CentOS快速安装Nginx的方法,nginx如何启动重启停止
1.防止 make: command not found,提前安装一些插件,取决于当前环境是否已安装,如果已经安装就不需要执行此命令 yum -y install gcc automake autoc ...
- 微信小程序-工具的下载与安装
QQ讨论群:785071190 安装开发工具 前往 开发者工具下载页面 ,根据自己的操作系统下载对应的安装包进行安装,有关开发者工具更详细的介绍可以查看 <开发者工具介绍> .工具安装非常 ...