bzoj 4003
左偏树。。。
打两个标记。。。和线段树一样,先下放cheng再下放*。
每回合并子树就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 300010
#define int long long
using namespace std;
int n,m,h[N];
int b[N],v[N];
int s[N],root[N];
vector<int>qi[N];
int c[N],ans[N],ans2[N];
int head[N],nxt[N],ver[N],tot;
void add(int a,int d)
{
tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=d;return ;
}
struct node
{
int l,r,w,d,lazy1,lazy2;
int pre;
node()
{
lazy2=;
}
}a[N*];int cnt;
int dep[N];
void push_down(int x)
{
int t1=a[x].l;int t2=a[x].r;
if(t1)
{
a[t1].w*=a[x].lazy2,a[t1].lazy1*=a[x].lazy2,a[t1].lazy2*=a[x].lazy2;
a[t1].w+=a[x].lazy1;
a[t1].lazy1+=a[x].lazy1;
}
if(t2)
{
a[t2].w*=a[x].lazy2,a[t2].lazy1*=a[x].lazy2,a[t2].lazy2*=a[x].lazy2;
a[t2].w+=a[x].lazy1;
a[t2].lazy1+=a[x].lazy1;
}
a[x].lazy1=;
a[x].lazy2=;
return ;
}
int merge(int x,int y)
{
if(!x||!y)return x+y;
if(a[x].w>a[y].w)swap(x,y);
push_down(x);
a[x].r=merge(a[x].r,y);
if(a[a[x].l].d<a[a[x].r].d)swap(a[x].l,a[x].r);
a[x].d=a[a[x].r].d+;
return x;
}
void dfs(int x)
{
root[x]=;
for(int i=;i<qi[x].size();i++)
{
a[++cnt].pre=qi[x][i];a[cnt].w=s[qi[x][i]];root[x]=merge(root[x],cnt);
}
for(int i=head[x];i;i=nxt[i])
{
dep[ver[i]]=dep[x]+;
dfs(ver[i]);
root[x]=merge(root[x],root[ver[i]]);
}
while(root[x]&&a[root[x]].w<h[x])
{
ans[x]++;
int y=a[root[x]].pre;
ans2[y]=dep[c[y]]-dep[x];
push_down(root[x]);
root[x]=merge(a[root[x]].l,a[root[x]].r);
}
if(root[x])
{
if(!b[x])
{
a[root[x]].w+=v[x];
a[root[x]].lazy1+=v[x];
}
else
{
a[root[x]].w*=v[x];
a[root[x]].lazy1*=v[x];
a[root[x]].lazy2*=v[x];
}
}
return ;
}
signed main()
{
scanf("%lld%lld",&n,&m);
for(int i=;i<=n;i++)scanf("%lld",&h[i]);
int t1;
for(int i=;i<=n;i++)
{
scanf("%lld",&t1);
add(t1,i);
scanf("%lld%lld",&b[i],&v[i]);
}
for(int i=;i<=m;i++)
{
scanf("%lld%lld",&s[i],&t1);
qi[t1].push_back(i);c[i]=t1;
}
dep[]=;
dfs();
while(root[]!=)
{
int y=a[root[]].pre;
ans2[y]=dep[c[y]]-dep[]+;
push_down(root[]);
root[]=merge(a[root[]].l,a[root[]].r);
}
for(int i=;i<=n;i++)printf("%lld\n",ans[i]);
for(int i=;i<=m;i++)printf("%lld\n",ans2[i]);
return ;
}
bzoj 4003的更多相关文章
- BZOJ 4003: [JLOI2015]城池攻占 左偏树 可并堆
https://www.lydsy.com/JudgeOnline/problem.php?id=4003 感觉就是……普通的堆啊(暴论),因为这个堆是通过递归往右堆里加一个新堆或者新节点的,所以要始 ...
- bzoj 4003: 城池攻占 左偏树
题目大意 http://www.lydsy.com/JudgeOnline/problem.php?id=4003 题解 一开始看漏条件了 题目保证当占领城池可以使攻击力乘上\(v_i\)时,一定有\ ...
- bzoj 4003 [JLOI2015]城池攻占 —— 左偏树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4003 其实蛮简单的,首先一个城市只会被其子树中的骑士经过,启发我们 dfs 序用可并堆合并子 ...
- BZOJ 4003 【JLOI2015】城池攻占
Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖, ...
- BZOJ 4003 JLOI2015 城池攻占
做法和APIO2012派遣 那道题目类似 在树上DFS,维护当前子树的小根堆 因为需要合并孩子们的信息,使用左偏树就可以了 每次弹出死亡骑士,对剩余骑士打上奖励标记 至于标记的下传和更改,只需要每次在 ...
- BZOJ 4003 左偏树
思路: 用到了左偏树合并复杂度是logn的性质 一开始先BFS一遍 打标记的左偏树 //By SiriusRen #include <cstdio> #include <cstrin ...
- BZOJ 4003 / Luogu P3261 [JLOI2015]城池攻占 (左偏树)
左偏树裸题,在树上合并儿子传上来的堆,然后小于当前结点防御值的就pop掉,pop的时候统计答案. 修改的话就像平衡树一样打懒标记就行了. 具体见代码 CODE #include<bits/std ...
- BZOJ 4003 (可并堆)
题面 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖, 其中 fi &l ...
- Luogu 3261 [JLOI2015]城池攻占
BZOJ 4003 需要实现一个可并堆. 每个点维护一个小根堆,然后一开始把所有骑士加入到它所在的点的小根堆当中,实际上空间是$O(m)$的,然后我们从上到下不断合并这个小根堆,合并完之后如果遇到堆顶 ...
随机推荐
- php实现设计模式之代理模式
<?php /* * 代理模式 * 为其他对象提供一种代理以控制对这个对象的访问. * 在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用 ...
- entityframework学习笔记--008-实体数据建模基础之继承关系映射TPH
Table per Hierarchy Inheritance 建模 1.让我们假设你有如图8-1中的表,Employee表包含hourly employees 和salaried employees ...
- JS正则表达式(JavaScript regular expression)
RegExp直接量和对象的创建 就像字符串和数字一样,程序中每个取值相同的原始类型直接量均表示相同的值,这是显而易见的.程序运行时每次遇到对象直接量(初始化表达式)诸如{}和[]的时候都会创建新对象. ...
- JS函数声明的问题
三个例子 var a = 10; 2 function test(){ 3 a = 100; 4 console.log(a); 5 console.log(this.a); 6 var a; 7 c ...
- [Android]使用Dagger 2依赖注入 - 自定义Scope(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5095426.html 使用Dagger 2依赖注入 - 自定义 ...
- iOS - NSMutableAttributedString富文本的实现
NSMutableAttributedString继承于NSAttributedString(带属性的字符串)能够简单快速实现富文本的效果;不多说直接上效果图和代码,通俗易懂: (一)效果图: (二) ...
- Java 策略模式和状态模式
本文是转载的,转载地址:大白话解释Strategy模式和State模式的区别 先上图: 本质上讲,策略模式和状态模式做得是同一件事:去耦合.怎么去耦合?就是把干什么(语境类)和怎么干(策略接口)分开, ...
- c#进阶之神奇的CSharp
CSharp 简写为c#,是一门非常年轻而又有活力的语言. CSharp的诞生 在2000年6月微软发布了c#这门新的语言.作为微软公司.NET 平台的主角,c#吸收了在他之前诞生的语言(c ...
- 启动/关闭oracle服务有三种方式
启动oracle服务有三种方式: 1 从控制面板 2 使用MS-DOS命令 3 通过Oracle Administration Assistant for WindowsNT -通过控制面板启动ora ...
- python爬虫学习(11) —— 也写个AC自动机
0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...