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)$的,然后我们从上到下不断合并这个小根堆,合并完之后如果遇到堆顶 ...
随机推荐
- CentOS6.7搭建LNMP环境
1:查看环境: [root@localhost ~]# cat /etc/redhat-release 2:关掉防火墙 #重启后生效开启 [root@localhost ~]# chkconfig i ...
- spider RPC高级特性
多租户 spider原生支持多租户部署,spider报文头对外开放了机构号.系统号两个属性用于支持多租户场景下的路由. 多租户场景下的路由可以支持下述几种模式: n 系统号: n 系统号+服务号( ...
- cookie入门
据我对cookie诞生背景的了解,cookie是由网景公司创建的,目的就是将用户的数据储存在客户端上.伴随的HTML5的出现,现在又有另外一个解决数据离线储存的方案,就是HTML5中的Web stor ...
- UICollectionView布局cell的三种方式
UICollectionViewFlowLayout里面: // 方法一 - (void)prepareLayout{} // 方法二 - (nullable NSArray<__kindof ...
- Android中点击隐藏软键盘最佳方法——Android开发之路4
Android中点击隐藏软键盘最佳方法 实现功能:点击EditText,软键盘出现并且不会隐藏,点击或者触摸EditText以外的其他任何区域,软键盘被隐藏: 1.重写dispatchTouchEve ...
- 几款Git GUI客户端工具
工欲善其事,必先利其器. 作为一名开发人员,你不可能不知道git,无论你是开发自己的开源项目还是和团队一起进行大规模产品的开发,git都已经是源代码管理工具的首选.当然,那些hardcore deve ...
- ORACLE lag()与lead() 函数
一.简介 lag与lead函数是跟偏移量相关的两个分析函数,通过这两个函数可以在一次查询中取出同一字段的前N行的数据(lag)和后N行的数据(lead)作为独立的列,从而更方便地进行进行数据过滤.这种 ...
- shell 脚本之判断语句 if 详解
使用 Linux 系统这么长时间,对 shell 脚本也算是比较熟悉.其实不管是搞开发,还是搞运维,shell 脚本都是必备的基本技能.这次抽时间好好总结一下 shell 方面的知识,综合的再学习一下 ...
- HTTP Method 之 Post VS. Get
引言 WebAPI 现在非常火的轻量服务框架,因其使用得使用了Http协议,并且具备了可协商内容(生成不同内容格式)等优势,所以在互联网业务中被广泛使用. 那作为HTTP最常用的两个方法Get和Pos ...
- (转)Java中的static关键字解析
转载: http://www.cnblogs.com/dolphin0520/p/3799052.html 一.static关键字的用途 在<Java编程思想>P86页有这样一段话: &q ...