P3261 [JLOI2015]城池攻占
思路
左偏树维护每个骑士的战斗力和加入的深度(因为只能向上跳)
注意做乘法的时候加法tag会受到影响
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
#define int long long
using namespace std;
struct Node{
int lson,rson,dis,num,mul,add,add_dep,sz,fa,id;
}LT[300100];
int n,m,u[300100<<1],v[300100<<1],fir[300100],nxt[300100<<1],cnt,fa[300100],S[300100],C[300100],A[300100],V[300100],H[300100],root[300100],ans_city[300100],ans_man[300100],dep[300100];
int find(int x){
if(LT[x].fa==x)
return x;
else
return LT[x].fa=find(LT[x].fa);
}
void pushup(int o){
LT[o].sz=LT[LT[o].lson].sz+LT[LT[o].rson].sz+1;
}
void pushdown(int o){
if(LT[o].mul!=1){
LT[LT[o].lson].num*=LT[o].mul;
LT[LT[o].rson].num*=LT[o].mul;
LT[LT[o].lson].mul*=LT[o].mul;
LT[LT[o].rson].mul*=LT[o].mul;
LT[LT[o].lson].add*=LT[o].mul;
LT[LT[o].rson].add*=LT[o].mul;
LT[o].mul=1;
}
if(LT[o].add){
LT[LT[o].lson].num+=LT[o].add;
LT[LT[o].rson].num+=LT[o].add;
LT[LT[o].lson].add+=LT[o].add;
LT[LT[o].rson].add+=LT[o].add;
LT[o].add=0;
}
}
int merge(int x,int y){
if(x*y==0)
return x+y;
pushdown(x);
pushdown(y);
if(LT[x].num>LT[y].num)
swap(x,y);
LT[x].rson=merge(LT[x].rson,y);
if(LT[LT[x].lson].dis<LT[LT[x].rson].dis)
swap(LT[x].lson,LT[x].rson);
LT[x].dis=LT[LT[x].rson].dis+1;
LT[LT[x].lson].fa=LT[LT[x].rson].fa=LT[x].fa=x;
pushup(x);
return x;
}
int pop(int u){
pushdown(u);
LT[LT[u].lson].fa=LT[u].lson;
LT[LT[u].rson].fa=LT[u].rson;
return LT[u].fa=merge(LT[u].lson,LT[u].rson);
}
void addedge(int ui,int vi){
++cnt;
u[cnt]=ui;
v[cnt]=vi;
nxt[cnt]=fir[ui];
fir[ui]=cnt;
}
void dfs_dep(int u){
dep[u]=dep[fa[u]]+1;
for(int i=fir[u];i;i=nxt[i]){
if(v[i]==fa[u])
continue;
dfs_dep(v[i]);
}
}
void dfs(int u){
for(int i=fir[u];i;i=nxt[i]){
if(v[i]==fa[u])
continue;
dfs(v[i]);
root[u]=merge(root[u],root[v[i]]);
}
while(LT[root[u]].sz>=1&<[root[u]].num<H[u]){
ans_city[u]++;
ans_man[LT[root[u]].id]=LT[root[u]].add_dep-dep[u];
root[u]=pop(root[u]);
}
if(A[u]){
LT[root[u]].num*=V[u];
LT[root[u]].mul*=V[u];
LT[root[u]].add*=V[u];
}
else {
LT[root[u]].num+=V[u];
LT[root[u]].add+=V[u];
}
}
void init(void){
for(int i=1;i<=m;i++){
LT[i].add_dep=dep[C[i]];
LT[i].add=0;
LT[i].mul=1;
LT[i].id=i;
LT[i].dis=1;
LT[i].sz=1;
LT[i].lson=LT[i].rson=0;
LT[i].fa=i;
LT[i].num=S[i];
root[C[i]]=merge(root[C[i]],i);
}
}
signed main(){
scanf("%lld %lld",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld",&H[i]);
}
for(int i=2;i<=n;i++){
scanf("%lld %lld %lld",&fa[i],&A[i],&V[i]);
if(fa[i]){
addedge(i,fa[i]);
addedge(fa[i],i);
}
}
for(int i=1;i<=m;i++){
scanf("%lld %lld",&S[i],&C[i]);
}
dfs_dep(1);
init();
dfs(1);
while(LT[root[1]].sz>=1){
ans_man[LT[root[1]].id]=LT[root[1]].add_dep;
root[1]=pop(root[1]);
}
for(int i=1;i<=n;i++){
printf("%lld\n",ans_city[i]);
}
for(int i=1;i<=m;i++) {
printf("%lld\n",ans_man[i]);
}
return 0;
}
P3261 [JLOI2015]城池攻占的更多相关文章
- [洛谷P3261] [JLOI2015]城池攻占(左偏树)
不得不说,这道题目是真的难,真不愧它的“省选/NOI-”的紫色大火题!!! 花了我晚自习前半节课看题解,写代码,又花了我半节晚自习调代码,真的心态爆炸.基本上改得和题解完全一样了我才过了这道题!真的烦 ...
- 洛谷P3261 [JLOI2015]城池攻占(左偏树)
传送门 每一个城市代表的点开一个小根堆,把每一个骑士合并到它开始攻占的城池所代表的点上 然后开始dfs,每一次把子树里那些还活着的骑士合并上来 然后再考虑当前点的堆,一直pop直到骑士全死光或者剩下的 ...
- P3261 [JLOI2015]城池攻占 题解
题目 小铭铭最近获得了一副新的桌游,游戏中需要用 \(m\) 个骑士攻占 \(n\) 个城池.这 \(n\) 个城池用 \(1\) 到 \(n\) 的整数表示.除 \(1\) 号城池外,城池 \(i\ ...
- P3261 [JLOI2015]城池攻占 (左偏树+标记下传)
左偏树还是满足堆的性质,节点距离就是离最近的外节点(无左或者右儿子 或者二者都没有)的距离,左偏性质就是一个节点左儿子的距离不小于右儿子,由此得:节点距离等于右儿子的距离+1. 本题就是对于每个节点 ...
- [洛谷P3261][JLOI2015]城池攻占
题目大意:有$n$个点的树,第$i$个节点有一个权值$h_i$,$m$个骑士,第$i$个骑士攻击力为$v_i$,一个骑士可以把从它开始的连续的父亲中比它小的节点攻破,攻破一个节点可以把攻击力加或乘一个 ...
- BZOJ 4003 / Luogu P3261 [JLOI2015]城池攻占 (左偏树)
左偏树裸题,在树上合并儿子传上来的堆,然后小于当前结点防御值的就pop掉,pop的时候统计答案. 修改的话就像平衡树一样打懒标记就行了. 具体见代码 CODE #include<bits/std ...
- 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,如果这个骑士的战斗力超过了这个门槛,他就会根据城 ...
随机推荐
- uvalive 4288 Cat Vs. Dog
题意: 有若干个观看者,要对节目进行投票,每张票一定让一直猫留下,一只狗下场,或者一只狗留下,一只猫下场. 如果某个观看者希望留下的动物下场了,或者希望下场的动物留下了,那么他就会离开. 给出若干个投 ...
- MongoDB With Spark遇到的2个错误,不能初始化和sample重复的key
1.$sample stage could not find a non-duplicate document while using a random cursor 这个问题比较难解决,因为我用mo ...
- STO(Security Token Offering)证券型通证、代币发行介绍
STO(Security Token Offering)证券型通证.代币发行介绍:STO(Security Token Offering)是一个新的融资概念.通过证券化的通证进行融资.早在2017年年 ...
- 【前端安全】JavaScript防流量劫持
劫持产生的原因和方式 在网页开发的访问过程中,http是我们主要的访问协议.我们知道http是一种无状态的连接.即没有验证通讯双方的身份,也没有验证信息的完整性,所以很容易受到篡改.运营商就是利用了这 ...
- 系统调用号、errno
最近老需要看系统调用号,errno,所以这里记一下 CentOS Linux release 7.2.1511 (Core) 3.10.0-327.el7.x86_64 [root@localhost ...
- Python智能检测编码并转码
#安装包工具 $pip3 install chardet #直接打开文件,中文显示乱码 >>> import chardet >>> f = open('test. ...
- Different between MB SD Connect Compact 5 and MB SD C4 Star Diagnostic Tool
MB SD C4 Star Diagnostic Tool is the professional MB Star Diagnostic Tools for benz cars and trucks. ...
- 自学Java第七周的总结
这一周里我将看过的知识点又复习了一遍,下个星期打算将题做一遍
- vue 去掉路由中的#
在router.js中修改, const router = new VueRouter({ mode: 'history', routes: [...] })
- iframe有那些缺点
1.页面样式调试麻烦,出现多个滚动条: 2.浏览器的后退按钮失效: 3.过多会增加服务器的HTTP请求: 4.小型的移动设备无法完全显示框架: 5.产生多个页面,不易管理: 6.不容易打印: 7.代码 ...