[BZOJ4003]城池攻占
Description
小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池。
这 n 个城池用 1 到 n 的整数表示。除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖,
其中 fi <i。也就是说,所有城池构成了一棵有根树。这 m 个骑士用 1 到 m 的整数表示,其
中第 i 个骑士的初始战斗力为 si,第一个攻击的城池为 ci。
每个城池有一个防御值 hi,如果一个骑士的战斗力大于等于城池的生命值,那么骑士就可
以占领这座城池;否则占领失败,骑士将在这座城池牺牲。占领一个城池以后,骑士的战斗力
将发生变化,然后继续攻击管辖这座城池的城池,直到占领 1 号城池,或牺牲为止。
除 1 号城池外,每个城池 i 会给出一个战斗力变化参数 ai;vi。若 ai =0,攻占城池 i 以后骑士战斗力会增加 vi;若 ai =1,攻占城池 i 以后,战斗力会乘以 vi。注意每个骑士是单独计算的。也就是说一个骑士攻击一座城池,不管结果如何,均不会影响其他骑士攻击这座城
的结果。
Input
第 1 行包含两个正整数 n;m,表示城池的数量和骑士的数量。
第 2 行包含 n 个整数,其中第 i 个数为 hi,表示城池 i 的防御值。
第 3 到 n +1 行,每行包含三个整数。其中第 i +1 行的三个数为 fi;ai;vi,分别表示管辖
这座城池的城池编号和两个战斗力变化参数。
第 n +2 到 n + m +1 行,每行包含两个整数。其中第 n + i 行的两个数为 si;ci,分别表
Output
输出 n + m 行,每行包含一个非负整数。其中前 n 行分别表示在城池 1 到 n 牺牲的骑士
Sample Input
50 20 10 10 30
1 1 2
2 0 5
2 0 -10
1 0 10
20 2
10 3
40 4
20 4
35 5
Sample Output
2
0
0
0
1
1
3
1
1
HINT
对于 100% 的数据,1 <= n;m <= 300000;
 1 <= fi<i; 1 <= ci <= n; -10^18 <= hi,vi,si <=
10^18;ai等于1或者2;当 ai =1 时,vi > 0;保证任何时候骑士战斗力值的绝对值不超过 10^18。
首先我们在每个节点死的是一段子树内的点经各种变化后得到的最小值,为了维护这个过程,我们考虑堆
然后我们发现乘法没有负数,因此两个点同时向上走以后之间的大小关系就不会改变了
因此我们直接在左偏树上打标记即可
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls ch[x][0]
#define rs ch[x][1]
#define int long long
#define M 300010
using namespace std;
int read()
{
char ch=getchar();int x=,f=;
while(ch>''||ch<'') {if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x*f;
}
int n,m,num;
int head[M],rt[M],a[M],v[M],dis[M],val[M],tag1[M],tag2[M],ch[M][];
int fa[M],deep[M],kill[M],dead[M],c[M],h[M];
struct point{int to,next;}e[M<<];
void add(int from,int to)
{
e[++num].next=head[from];
e[num].to=to;
head[from]=num;
}
void pushdown(int x,int t1,int t2)
{
val[x]*=t1,val[x]+=t2;
tag1[x]*=t1;tag2[x]*=t1,tag2[x]+=t2;
}
void push(int x)
{
pushdown(ls,tag1[x],tag2[x]);
pushdown(rs,tag1[x],tag2[x]);
tag1[x]=,tag2[x]=;
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
push(x),push(y);
if(val[x]>val[y]) swap(x,y);
ch[x][]=merge(rs,y);
if(dis[ls]<dis[rs]) swap(ls,rs);
dis[x]=dis[rs]+;
return x;
}
void dfs(int x)
{
deep[x]=deep[fa[x]]+;
for(int i=head[x];i;i=e[i].next)
{
int to=e[i].to;dfs(to);
rt[x]=merge(rt[x],rt[to]);
}
while(rt[x]&&val[rt[x]]<h[x])
{
push(rt[x]);
dead[x]++;
kill[rt[x]]=deep[c[rt[x]]]-deep[x];
rt[x]=merge(ch[rt[x]][],ch[rt[x]][]);
}
if(a[x]) pushdown(rt[x],v[x],);
else pushdown(rt[x],,v[x]);
}
#undef int
int main()
{
#define int long long
n=read();m=read();
for(int i=;i<=n;i++) h[i]=read();
for(int i=;i<=n;i++)
{
fa[i]=read(),a[i]=read();
v[i]=read(),add(fa[i],i);
}
for(int i=;i<=m;i++)
{
val[i]=read(),c[i]=read();
tag1[i]=,tag2[i]=;
rt[c[i]]=merge(rt[c[i]],i);
}
dfs();
while(rt[])//如果一直没死
{
push(rt[]);
kill[rt[]]=deep[c[rt[]]];
rt[]=merge(ch[rt[]][],ch[rt[]][]);
}
for(int i=;i<=n;i++) printf("%lld\n",dead[i]);
for(int i=;i<=m;i++) printf("%lld\n",kill[i]);
return ;
}
[BZOJ4003]城池攻占的更多相关文章
- bzoj-4003   城池攻占
		题意: 给出一个n个结点的有根树,和m个骑士: 树上的结点--城池有一个防御值,骑士有一个战斗力: 当骑士的战斗力大于等于城池时,城池被攻破.骑士的战斗力变化,并向树上的父节点前进: 否则骑士死亡. ... 
- 【BZOJ4003】[JLOI2015]城池攻占 可并堆
		[BZOJ4003][JLOI2015]城池攻占 Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号 ... 
- [bzoj4003][JLOI2015]城池攻占_左偏树
		城池攻占 bzoj-4003 JLOI-2015 题目大意:一颗n个节点的有根数,m个有初始战斗力的骑士都站在节点上.每一个节点有一个standard,如果这个骑士的战斗力超过了这个门槛,他就会根据城 ... 
- 【BZOJ】【4003】【JLOI2015】城池攻占
		可并堆 QAQ改了一下午……最终弃疗求助zyf……居然被秒了QAQ真是弱到不行(zyf太神了Orz) 还是先考虑部分分的做法: 1.$n,m\leq 3000$:可以暴力模拟每个骑士的攻打过程,也可以 ... 
- BZOJ_4003_[JLOI2015]城池攻占_可并堆
		BZOJ_4003_[JLOI2015]城池攻占_可并堆 Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 ... 
- 「JLOI2015」城池攻占 解题报告
		「JLOI2015」城池攻占 注意到任意两个人的战斗力相对大小的不变的 可以离线的把所有人赛到初始点的堆里 然后做启发式合并就可以了 Code: #include <cstdio> #in ... 
- [洛谷P3261] [JLOI2015]城池攻占(左偏树)
		不得不说,这道题目是真的难,真不愧它的“省选/NOI-”的紫色大火题!!! 花了我晚自习前半节课看题解,写代码,又花了我半节晚自习调代码,真的心态爆炸.基本上改得和题解完全一样了我才过了这道题!真的烦 ... 
- BZOJ4003 [JLOI2015]城池攻占 左偏树 可并堆
		欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4003 题意概括 题意有点复杂,直接放原题了. 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑 ... 
- 【BZOJ4003】【JLOI2015】城池攻占(左偏树)
		题面 题目描述 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池.这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖,其中 fi ... 
随机推荐
- ggplot2画图小试
			# 注意aes(x=wt, y=mpg)中的wt不是字符"wt",因此它是属性字段名(例如,EXCel中字段名有Student,那就是Student,而不是"Studen ... 
- Linux 常用资源
			kernel:ftp://kernel.orgcnkernel:http://www.cnkernel.orgoldlinux:http://www.oldlinux.orgminix3:http:/ ... 
- 干货 | 蚂蚁金服是如何实现经典服务化架构往 Service Mesh 方向的演进的?
			干货 | 蚂蚁金服是如何实现经典服务化架构往 Service Mesh 方向的演进的? https://www.sohu.com/a/235575064_99940985 干货 | 蚂蚁金服是如何实现 ... 
- spring data jpa 遇到的问题
			org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.O ... 
- 【tensorflow】
			运行计算图 session.run() https://blog.csdn.net/sinat_39372048/article/details/80868168 赋值 tf.assign() tf. ... 
- JS获取浏览器信息及屏幕分辨率
			因为vue有自己的生命周期,初始化数据的时候,可以在钩子函数created()函数里初始化数据,也可以在mounted()函数里获取,但是两者是不同的,获取浏览器和屏幕分辨率的时候,不能在create ... 
- CMDB实现的四种方式
			第一种(agent): 这种方式是通过向每一台服务器安装agent脚本,然后通过中控机的API,来收集所需要的数据,最后放到数据库中,在通过web的方式显示出来. 实现流程图: 1.录入资产(主机名, ... 
- shell_01
			定义变量: name='qwer' 不解析任何字符 name="qwer" 会解析$和\特殊字符 name1=123;name2=456 定义多个变量 now_date=`date ... 
- 深入浅出java IO模型
			一.同步和异步 同步:一个事件或者任务的执行,会使整个流程暂时等待,也就是说如果有多个任务要执行,必须要逐个进行. 异步:一个事件或者任务的执行,不会使整个流程暂时等待,也就是说如果有多个任务要执行, ... 
- UVA10534:Wavio Sequence(最长递增和递减序列 n*logn)(LIS)好题
			题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=68553#problem/B 题目要求: Wavio是一个整数序列,具有以下特性 ... 
