[洛谷P3261] [JLOI2015]城池攻占(左偏树)
不得不说,这道题目是真的难,真不愧它的“省选/NOI-”的紫色大火题!!!
花了我晚自习前半节课看题解,写代码,又花了我半节晚自习调代码,真的心态爆炸。基本上改得和题解完全一样了我才过了这道题!真的烦。没事,那接下来我来完全把这道题搞透。
Part 1 理解题目
至少我一开始不知道为什么要用左偏树,甚至我看题解一开始也都没弄懂,所以先把题目弄清楚。
首先我们由题可以知道,这要求我们从建好的树的叶子节点开始往上推,有些骑士到特定的点才会出现,check一下骑士能否攻占城池,再记录进答案,更新战斗力,这就很容易想到左偏树可并堆了。
Part 2 解题思想
既然每到一个点会出现一堆的新骑士,所以我们可以在那些点连一些“隐藏边”,到这个点时用链式前向星扫一遍加到一个小根堆中,然后把这个点以下的所有剩下的骑士合并到这个堆中(板子),然后在check时挨个弹出堆顶,如果不能占领就记入答案,能占领我们就要考虑更新骑士,我们不可能直接更新整个堆中的骑士,这样会被硬生生卡成O(n)的修改,所以我们考虑放一个lazy标记在堆顶,每一次合并和删除的时候再下放就可以了。
part 3 code
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<ctime>
#include<queue>
#include<stack>
#define lst long long
#define rg register
#define N 300050
using namespace std; int n,m,cnt;
bool type[N];
int fir[N],deep[N],up[N],dead[N];
lst key[N],def[N],v[N],mul[N],plu[N];
struct edge{
int to,nxt;
}a[N],b[N];
int head[N],ft[N],ls[N],rs[N],dis[N]; inline lst read()
{
rg lst s=,m=;rg char ch=getchar();
while(ch!='-'&&(ch<''||ch>''))ch=getchar();
if(ch=='-')m=-,ch=getchar();
while(ch>=''&&ch<='')s=(s<<)+(s<<)+ch-'',ch=getchar();
return m*s;
} void cover(rg int A,rg lst c,rg lst j)
{
if(!A)return;
key[A]*=c,key[A]+=j;
mul[A]*=c,plu[A]*=c,plu[A]+=j;
} void pushdown(rg int A)
{
cover(ls[A],mul[A],plu[A]);
cover(rs[A],mul[A],plu[A]);
mul[A]=,plu[A]=;
} int Merge(rg int A,rg int B)
{
if(!A||!B)return A+B;
if(key[A]>key[B])swap(A,B);
pushdown(A),pushdown(B);
rs[A]=Merge(rs[A],B);
if(dis[ls[A]]<dis[rs[A]])swap(ls[A],rs[A]);
dis[A]=dis[rs[A]]+;
return A;
} int Delete(rg int A)
{
pushdown(A);
return Merge(ls[A],rs[A]);
} int dfs(rg int now,rg int fm)
{
rg int A=,B;
deep[now]=deep[fm]+;
for(rg int i=ft[now];i;i=b[i].nxt)A=Merge(A,b[i].to);
for(rg int i=head[now];i;i=a[i].nxt)
{
B=dfs(a[i].to,now);
A=Merge(A,B);
}
while(key[A]<def[now]&&A)
{
dead[now]++;up[A]=deep[now];
A=Delete(A);
}
if(type[now])cover(A,v[now],);
else cover(A,,v[now]);
return A;
} int main()
{
n=read(),m=read();
for(rg int i=;i<=n;++i)def[i]=read();
for(rg int i=;i<=n;++i)
{
rg int go=read();
a[++cnt]=(edge){i,head[go]};head[go]=cnt;
type[i]=read(),v[i]=read();
}cnt=;
for(rg int i=;i<=m;++i)
{
key[i]=read(),fir[i]=read();
b[++cnt]=(edge){i,ft[fir[i]]};ft[fir[i]]=cnt;
}
dfs(,);
for(rg int i=;i<=n;++i)printf("%d\n",dead[i]);
for(rg int i=;i<=m;++i)printf("%d\n",deep[fir[i]]-up[i]);
return ;
}
到此为止,顺便膜拜一下大佬zsy,这是他的城池攻占:
[洛谷P3261] [JLOI2015]城池攻占(左偏树)的更多相关文章
- BZOJ 4003 / Luogu P3261 [JLOI2015]城池攻占 (左偏树)
左偏树裸题,在树上合并儿子传上来的堆,然后小于当前结点防御值的就pop掉,pop的时候统计答案. 修改的话就像平衡树一样打懒标记就行了. 具体见代码 CODE #include<bits/std ...
- [JLOI2015]城池攻占 左偏树
题目描述 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池.这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖,其中 fi &l ...
- [luogu3261 JLOI2015] 城池攻占 (左偏树+标记)
传送门 Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池.这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的 ...
- BZOJ 4003: [JLOI2015]城池攻占 左偏树 可并堆
https://www.lydsy.com/JudgeOnline/problem.php?id=4003 感觉就是……普通的堆啊(暴论),因为这个堆是通过递归往右堆里加一个新堆或者新节点的,所以要始 ...
- 洛谷P3261 [JLOI2015]城池攻占(左偏树)
传送门 每一个城市代表的点开一个小根堆,把每一个骑士合并到它开始攻占的城池所代表的点上 然后开始dfs,每一次把子树里那些还活着的骑士合并上来 然后再考虑当前点的堆,一直pop直到骑士全死光或者剩下的 ...
- [洛谷P3261][JLOI2015]城池攻占
题目大意:有$n$个点的树,第$i$个节点有一个权值$h_i$,$m$个骑士,第$i$个骑士攻击力为$v_i$,一个骑士可以把从它开始的连续的父亲中比它小的节点攻破,攻破一个节点可以把攻击力加或乘一个 ...
- BZOJ4003 [JLOI2015]城池攻占 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4003 题意概括 题意有点复杂,直接放原题了. 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑 ...
- [BZOJ4003][JLOI2015]城池攻占(左偏树)
这题有多种做法,一种是倍增预处理出每个点往上走2^i步最少需要的初始战斗力,一种是裸的启发式合并带标记splay. 每个点合并能攻占其儿子的所有骑士,删去所有无法攻占这个城市的骑士并记录答案. 注意到 ...
- bzoj 4003 [JLOI2015]城池攻占 —— 左偏树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4003 其实蛮简单的,首先一个城市只会被其子树中的骑士经过,启发我们 dfs 序用可并堆合并子 ...
随机推荐
- ElasticSearch 入门介绍
tags: 第三方 lucene [toc] 1. what Elastic Search(ES)是什么 全文检索和lucene 全文检索 优点:高效,准确,分词全文检索允许用户输入一些关键字,从数据 ...
- java 中的引用类型
GC基本原理 GC (Garbage Collection)的基本原理:将内存中不再被使用的对象进行回收,GC中用于回收的方法称为收集器,由于GC需要消耗一些资源和时间,Java在对对象的生命周期特征 ...
- 2018-8-10-cant-found-Microsoft.VSSDK.BuildTools.15.0.26201
title author date CreateTime categories cant found Microsoft.VSSDK.BuildTools.15.0.26201 lindexi 201 ...
- [Luogu1220]关路灯(区间dp)
[Luogu1220]关路灯 题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏 ...
- ltp-ddt eth iperf
ETH_S_PERF_IPERF_TCP_8K_1448B source 'common.sh'; run_iperf.sh -m -M 1500 -f M -d -t 60 -w 8K run_ip ...
- [洛谷P3958] NOIP2017 奶酪
问题描述 现有一块大奶酪,它的高度为 h,它的长度和宽度我们可以认为是无限大的,奶酪 中间有许多 半径相同 的球形空洞.我们可以在这块奶酪中建立空间坐标系,在坐标系中, 奶酪的下表面为z = 0,奶酪 ...
- FMDB复习
// colum/列/字段// row/行/记录// 主键的作用是唯一标识一条记录// sql语句注意:不区分大小写,以分号结束(不要分号也行?) // 如果增加字段,可能要指定数据类型,S ...
- Xcode模拟器快捷键
command + 左右 = 横竖屏旋转 command + H + H = 切入层级后台模式
- ckeditor富文本编辑器的使用和图片上传,复制粘贴图片上传
自动导入Word图片,或者粘贴Word内容时自动上传所有的图片,并且最终保留Word样式,这应该是Web编辑器里面最基本的一个需求功能了.一般情况下我们将Word内容粘贴到Web编辑器(富文本编辑器) ...
- 20180715-Java日期时间
import java.util.Date;public class DateDemo{ public static void main(String[] args){ //初始化Date对象 Dat ...