[JLOI2015]城池攻占
题目描述
小铭铭最近获得了一副新的桌游,游戏中需要用 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。注意每个骑士是单独计算的。也就是说一个骑士攻击一座城池,不管结果如何,均不会影响其他骑士攻击这座城池的结果。
现在的问题是,对于每个城池,输出有多少个骑士在这里牺牲;对于每个骑士,输出他攻占的城池数量。
输入输出格式
输入格式:
第 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,分别表示初始战斗力和第一个攻击的城池。
输出格式:
输出 n + m 行,每行包含一个非负整数。其中前 n 行分别表示在城池 1 到 n 牺牲的骑士数量,后 m 行分别表示骑士 1 到 m 攻占的城池数量。
输入输出样例
2
2
0
0
0
1
1
3
1
1
说明
对于 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。
每一个点维护一个小根堆
从叶子节点向上处理,把小于h[i]的pop掉,修改后和父亲合并
至于修改,给左偏堆打上延迟标记
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long lol;
struct Node
{
int next,to;
}edge[];
struct ZYYS
{
int dis;
lol v,add,mul;
int l,r;
}t[];
int head[],num,rt[];
lol h[],die[];
int death[],a[],n,m;
lol v[];
int fa[],dep[],c[];
void add(int u,int v)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
void update(int x,lol add,lol mul)
{
if (!x) return;
if (add==&&mul==) return;
t[x].v=t[x].v*mul+add;
t[x].add=mul*t[x].add+add;
t[x].mul*=mul;
}
void pushdown(int x)
{
update(t[x].l,t[x].add,t[x].mul);
update(t[x].r,t[x].add,t[x].mul);
t[x].add=;t[x].mul=;
}
int merge(int a,int b)
{
if (!a||!b) return a+b;
if (t[a].v>t[b].v) swap(a,b);
pushdown(a);pushdown(b);
t[a].r=merge(t[a].r,b);
if (t[t[a].l].dis<t[t[a].r].dis) swap(t[a].l,t[a].r);
t[a].dis=t[t[a].r].dis+;
return a;
}
void dfs(int x)
{int i;
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
dep[v]=dep[x]+;
dfs(v);
rt[x]=merge(rt[x],rt[v]);
}
while (rt[x]&&t[rt[x]].v<h[x])
{
death[x]++;
pushdown(rt[x]);
die[rt[x]]=x;
rt[x]=merge(t[rt[x]].l,t[rt[x]].r);
}
if (a[x]) update(rt[x],,v[x]);
else update(rt[x],v[x],);
}
int main()
{int i;
cin>>n>>m;
for (i=;i<=n;i++)
scanf("%lld",&h[i]);
for (i=;i<=n;i++)
{
scanf("%d%d%lld",&fa[i],&a[i],&v[i]);
add(fa[i],i);
}
for (i=;i<=m;i++)
{
scanf("%lld%d",&t[i].v,&c[i]);
t[i].mul=;t[i].add=;
rt[c[i]]=merge(rt[c[i]],i);
}
dep[]=;
dfs();
for (i=;i<=n;i++)
printf("%d\n",death[i]);
for (i=;i<=m;i++)
printf("%d\n",dep[c[i]]-dep[die[i]]);
}
[JLOI2015]城池攻占的更多相关文章
- BZOJ_4003_[JLOI2015]城池攻占_可并堆
BZOJ_4003_[JLOI2015]城池攻占_可并堆 Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 ...
- 【BZOJ4003】[JLOI2015]城池攻占 可并堆
[BZOJ4003][JLOI2015]城池攻占 Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号 ...
- [bzoj4003][JLOI2015]城池攻占_左偏树
城池攻占 bzoj-4003 JLOI-2015 题目大意:一颗n个节点的有根数,m个有初始战斗力的骑士都站在节点上.每一个节点有一个standard,如果这个骑士的战斗力超过了这个门槛,他就会根据城 ...
- [洛谷P3261] [JLOI2015]城池攻占(左偏树)
不得不说,这道题目是真的难,真不愧它的“省选/NOI-”的紫色大火题!!! 花了我晚自习前半节课看题解,写代码,又花了我半节晚自习调代码,真的心态爆炸.基本上改得和题解完全一样了我才过了这道题!真的烦 ...
- [JLOI2015]城池攻占 左偏树
题目描述 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池.这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖,其中 fi &l ...
- BZOJ4003[JLOI2015]城池攻占——可并堆
题目描述 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖, 其中 fi ...
- BZOJ4003 [JLOI2015]城池攻占 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4003 题意概括 题意有点复杂,直接放原题了. 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑 ...
- 【左偏树】【P3261】 [JLOI2015]城池攻占
Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池.这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖,其 ...
- BZOJ4003:[JLOI2015]城池攻占——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4003 https://www.luogu.org/problemnew/show/P3261 小铭 ...
随机推荐
- 『开源重编译』System.Data.SQLite.dll 自适应 x86 x64 AnyCPU 重编译
背景: > System.Data.SQLite.dll 程序集 不能良好的支持 AngCPU 格式 System.Data.SQLite.dll 在 适应 x86 和 x64 有三个方案: & ...
- 第1次作业:这是我的一个响亮的标题X!
1.我是回答问题的部分 part 1: 从小学开始,我就觉得写作文是一件很痛苦的事情.(痛苦ing) 所以呢,选择工科好像就是理所当然的. 至于为什么选择计算机,主要原因就是不知道应该选什么,正好看到 ...
- 第十四周实验报告:实验四 Android程序设计
20162317袁逸灏 第十四周实验报告:实验四 Android程序设计 实验内容 Android Studio 实验要求 学会使用Android Studio 学习 活动 以及相关知识内容 学习 U ...
- 201621123043 《Java程序设计》第2周学习总结
1.本周学习总结 使用jdk文档查阅函数功能及代码 用switch语句是在每个case中可能在第一行是sc.nextLine;来给回车赋值: 在使用循环的时候要注意循环返回的条件,否则陷入死循环可能会 ...
- PYTHON 词云
#!/usr/bin/env python # -*- coding:utf-8 -*- import matplotlib.pyplot as plt from wordcloud import W ...
- EasyUi中对话框。
html页面代码: <head id="Head1" runat="server"> <meta http-equiv="Conte ...
- Table点击某个td获取当前列的头名称
jq代码: $("td").click(function () { var tdHtml = $(this).attr("html"); var index = ...
- 为什么 asnyc await 可以提高web程序的吞吐量
(转网上一段话) Web程序天生就是多线程的,且web线程都是跑的线程池线程(使用线程池线程是为了避免不断创建.销毁线程所造成的资源成本浪费),而线程池线程可使用线程数量是一定的,尽管可以设置,但它还 ...
- c# aynsc 和 await
static void Main(string[] args) { Print(); Console.WriteLine("这是主线程"); } public static a ...
- c++中模板是什么?为什么要定义模板?
一.c++中模板是什么? 首先: int Max(int x, int y) { return x > y ? x : y; } float Max(float a,float b) { ret ...