左偏树 (p3261) 对我来说是一道进阶题
题意:有n座城池,m个人;
每座城池有一个耐久度;
每座城池有一个父亲城池(肯定会形成一棵树),还有flag base (这个看题意)
每个人有一个战力值和一个开始进攻的城池序号;
问:1.每个城池能够使将领死亡的死亡数 2.每个将领能够攻占的城池数量;
思路,这道题是一颗树,所以自然而然的想到用dfs传到根节点,再传回去这种做法;
那么在这种做法下,我们建立最小堆,对每一个节点建立一个最小堆,然后遍历的时候,将小于limit[]的将领弹出;
这个时候需要更新答案, 这个城池的将领死亡数量+1;这个将领攻占的城池数量;
然后 剩下的将领有一个val需要更新 这个时候我们不是直接更新,而是用一个懒惰节点去降低复杂度;
一步一步传给子节点更新;
#include<cstdio>
#include<algorithm>
#include<math.h>
#include<string.h>
using namespace std;
typedef long long ll;
const ll maxn=3e5+;
ll flag[maxn],base[maxn]; //城池的val更新方式
ll ch[maxn][]; //子节点
ll val[maxn],guishu[maxn]; //将领的战力值和第一个城池
ll root[maxn]; //每一个城池的根节点;
ll dep[maxn],dis[maxn]; //dep是用来计算将领的攻占城池数量的, dis是左偏树的深度;
ll ans1[maxn],ans2[maxn]; //城池答案,将领答案;
ll mul[maxn],add[maxn]; //懒惰标记
ll limit[maxn]; //城池耐久值
struct node //邻接表
{
ll v,next;
}G[maxn]; ll head[maxn];ll num=-;
void build(ll u,ll v)
{
G[++num].v=v;G[num].next=head[u];head[u]=num;
}
void cov(ll x,ll c,ll j)
{
if(!x) return;
val[x]*=c;val[x]+=j; //这里有一个乘和一个加,自然是先乘后加; 这是根据下文这两句来确定的
mul[x]*=c; //这里的确定方式是将已经有的懒惰节点的值与本次加进来的懒惰节点更新;
//已经有的,自然那些要+的,也要乘上这次的数,然后再加上这次要加的数
//注:下次看这里看不懂的话,多看一下肯定会懂的
add[x]*=c;add[x]+=j;
}
void pushdown(ll x)
{ //左右儿子都得更新
cov(ch[x][],mul[x],add[x]);
cov(ch[x][],mul[x],add[x]);
mul[x]=;add[x]=;
}
ll Merge(ll x,ll y)
{
if(!x||!y) return x+y;
pushdown(x);pushdown(y);
if(val[x]>val[y]) swap(x,y);
ch[x][]=Merge(ch[x][],y);
if(dis[ch[x][]]<dis[ch[x][]]) swap(ch[x][],ch[x][]);
dis[x]=dis[ch[x][]]+;
return x;
} void dfs(ll u,ll fa)
{
dep[u]=dep[fa]+;
for(ll i=head[u];i!=-;i=G[i].next){
ll v=G[i].v;
dfs(v,u);
root[u]=Merge(root[u],root[v]);
}
while(root[u]&&val[root[u]]<limit[u]){
pushdown(root[u]);
ans1[u]++;
ans2[root[u]]=dep[guishu[root[u]]]-dep[u];
ll t=root[u];
root[u]=Merge(ch[t][],ch[t][]);
}
if(flag[u]) cov(root[u],base[u],);
else cov(root[u],,base[u]);
}
int main()
{
ll n,m;
memset(head,-,sizeof(head));
scanf("%lld%lld",&n,&m);
for(ll i=;i<=n;i++) scanf("%lld",&limit[i]);
for(ll i=;i<=n;i++){
ll u;
scanf("%lld%lld%lld",&u,&flag[i],&base[i]);
build(u,i);
}
for(ll i=;i<=m;i++){
scanf("%lld%lld",&val[i],&guishu[i]);
ll t=guishu[i];
mul[i]=;
if(!root[t]) root[t]=i;
else root[t]=Merge(root[t],i);
}
dfs(,);
while(root[]){
pushdown(root[]);
ans2[root[]]=dep[guishu[root[]]];
root[]=Merge(ch[root[]][],ch[root[]][]);
}
for(ll i=;i<=n;i++) printf("%lld\n",ans1[i]);
for(ll i=;i<=n;i++) printf("%lld\n",ans2[i]);
return ;
}
左偏树 (p3261) 对我来说是一道进阶题的更多相关文章
- 洛谷P4331 [BOI2004] Sequence 数字序列 [左偏树]
题目传送门 数字序列 题目描述 给定一个整数序列 a1,a2,⋅⋅⋅,an ,求出一个递增序列 b1<b2<⋅⋅⋅<bn ,使得序列 ai 和 bi 的各项之差的绝对 ...
- 【BZOJ2809】[APIO2012] dispatching(左偏树例题)
点此看题面 大致题意: 有\(N\)名忍者,每名忍者有三个属性:上司\(B_i\),薪水\(C_i\)和领导力\(L_i\).你要选择一个忍者作为管理者,然后在所有被他管理的忍者中选择若干名忍者,使薪 ...
- 【左偏树】【P3261】 [JLOI2015]城池攻占
Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池.这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖,其 ...
- BZOJ 4003 / Luogu P3261 [JLOI2015]城池攻占 (左偏树)
左偏树裸题,在树上合并儿子传上来的堆,然后小于当前结点防御值的就pop掉,pop的时候统计答案. 修改的话就像平衡树一样打懒标记就行了. 具体见代码 CODE #include<bits/std ...
- [洛谷P3261] [JLOI2015]城池攻占(左偏树)
不得不说,这道题目是真的难,真不愧它的“省选/NOI-”的紫色大火题!!! 花了我晚自习前半节课看题解,写代码,又花了我半节晚自习调代码,真的心态爆炸.基本上改得和题解完全一样了我才过了这道题!真的烦 ...
- P3261 [JLOI2015]城池攻占 (左偏树+标记下传)
左偏树还是满足堆的性质,节点距离就是离最近的外节点(无左或者右儿子 或者二者都没有)的距离,左偏性质就是一个节点左儿子的距离不小于右儿子,由此得:节点距离等于右儿子的距离+1. 本题就是对于每个节点 ...
- 左偏树(Leftist Heap/Tree)简介及代码
左偏树是一种常用的优先队列(堆)结构.与二叉堆相比,左偏树可以高效的实现两个堆的合并操作. 左偏树实现方便,编程复杂度低,而且有着不俗的效率表现. 它的一个常见应用就是与并查集结合使用.利用并查集确定 ...
- 『左偏树 Leftist Tree』
新增一道例题 左偏树 Leftist Tree 这是一个由堆(优先队列)推广而来的神奇数据结构,我们先来了解一下它. 简单的来说,左偏树可以实现一般堆的所有功能,如查询最值,删除堆顶元素,加入新元素等 ...
- BZOJ2333 [SCOI2011]棘手的操作 堆 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2333 题意概括 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i ...
随机推荐
- 《NVM-Express-1_4-2019.06.10-Ratified》学习笔记(5.2)-- Asynchronous Event Request command
5.2 异步事件请求命令 异步事件用于当状态.错误.健康信息这些事件发生时通知主机软件.为了使能这个controller报告的异步事件,主机软件需要提交一个或多个异步事件请求命令到controller ...
- 判断是否网络连通 .net Ping
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using S ...
- 开放系统互联(OSI)模型
开放系统互联(OSI)模型 是由国际标准化组织(ISO)于1984年提出的一种标准参考模型,是一种关于由不同供应商提供的不同设备和应用软件之间的网络通信的概念性框架结构.它被公认为是计算机通信和 in ...
- flask操作
models.py class CompanyGoodsModel(Base): id=Column(Integer, primary_key=True) company_id = Column(In ...
- JS高级---案例:验证用户输入的是不是邮箱
案例:验证用户输入的是不是邮箱 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...
- MySQL5.5升级至5.7
一.下载免安装MySQL5.7包 下载页面 下载链接 二.替换mysql的安装目录 解压mysql5.7 tar -zxf mysql-5.7.23-linux-glibc2.12-x86_64.ta ...
- pytest学习2-运行方式
pytest常用运行方式 运行目录及子包下的所有用例: pytest 目录名 运行指定模块所有用例: pytest test_reg.py pytest test_reg.py::TestClass: ...
- Java基本语法--变量
本篇博客主要介绍了Java基本语法中变量(variable)d的使用,变量是指内存中的一个存储区域,用于在内存中保存数据,在该区域的数据可以在同一类型范围内不断变化.变量是程序中最基本的存储单元.包含 ...
- LitElement(六)生命周期
1.概述 基于LitElement的组件通过响应观察到的属性更改而异步更新. 属性更改是分批进行的,如果在请求更新后,更新开始之前,发生更多属性更改,则所有更改都将捕获在同一次更新中. 在较高级别上, ...
- 接口自动化框架(Pytest,Allure,Yaml)
框架链接:https://www.jianshu.com/p/e31c54bf15ee 目前是基于他的框架做了些改动(主要是session.action()和json格式传参). 后续优化,应该主要思 ...