思路

左偏树维护每个骑士的战斗力和加入的深度(因为只能向上跳)

注意做乘法的时候加法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&&LT[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]城池攻占的更多相关文章

  1. [洛谷P3261] [JLOI2015]城池攻占(左偏树)

    不得不说,这道题目是真的难,真不愧它的“省选/NOI-”的紫色大火题!!! 花了我晚自习前半节课看题解,写代码,又花了我半节晚自习调代码,真的心态爆炸.基本上改得和题解完全一样了我才过了这道题!真的烦 ...

  2. 洛谷P3261 [JLOI2015]城池攻占(左偏树)

    传送门 每一个城市代表的点开一个小根堆,把每一个骑士合并到它开始攻占的城池所代表的点上 然后开始dfs,每一次把子树里那些还活着的骑士合并上来 然后再考虑当前点的堆,一直pop直到骑士全死光或者剩下的 ...

  3. P3261 [JLOI2015]城池攻占 题解

    题目 小铭铭最近获得了一副新的桌游,游戏中需要用 \(m\) 个骑士攻占 \(n\) 个城池.这 \(n\) 个城池用 \(1\) 到 \(n\) 的整数表示.除 \(1\) 号城池外,城池 \(i\ ...

  4. P3261 [JLOI2015]城池攻占 (左偏树+标记下传)

    左偏树还是满足堆的性质,节点距离就是离最近的外节点(无左或者右儿子  或者二者都没有)的距离,左偏性质就是一个节点左儿子的距离不小于右儿子,由此得:节点距离等于右儿子的距离+1. 本题就是对于每个节点 ...

  5. [洛谷P3261][JLOI2015]城池攻占

    题目大意:有$n$个点的树,第$i$个节点有一个权值$h_i$,$m$个骑士,第$i$个骑士攻击力为$v_i$,一个骑士可以把从它开始的连续的父亲中比它小的节点攻破,攻破一个节点可以把攻击力加或乘一个 ...

  6. BZOJ 4003 / Luogu P3261 [JLOI2015]城池攻占 (左偏树)

    左偏树裸题,在树上合并儿子传上来的堆,然后小于当前结点防御值的就pop掉,pop的时候统计答案. 修改的话就像平衡树一样打懒标记就行了. 具体见代码 CODE #include<bits/std ...

  7. BZOJ_4003_[JLOI2015]城池攻占_可并堆

    BZOJ_4003_[JLOI2015]城池攻占_可并堆 Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 ...

  8. 【BZOJ4003】[JLOI2015]城池攻占 可并堆

    [BZOJ4003][JLOI2015]城池攻占 Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号 ...

  9. [bzoj4003][JLOI2015]城池攻占_左偏树

    城池攻占 bzoj-4003 JLOI-2015 题目大意:一颗n个节点的有根数,m个有初始战斗力的骑士都站在节点上.每一个节点有一个standard,如果这个骑士的战斗力超过了这个门槛,他就会根据城 ...

随机推荐

  1. keras可视化pydot graphviz问题

    Keras中提供了一个神经网络可视化的函数plot,并可以将可视化结果保存在本地.plot使用方法如下: from keras.utils.visualize_util import plot plo ...

  2. sitecore系统教程之限制对客户端的访问

    如果您为不同目的配置服务器,根据角色,您可能需要禁用Sitecore客户端.例如,如果配置内容交付服务器或处理服务器,则无需访问客户端应用程序,因此在这种情况下,建议禁用客户端. 为防止未经授权访问S ...

  3. web基础,用html元素制作web页面

    用div,form制作登录页面,尽可能做得漂亮. 练习使用下拉列表选择框,无序列表,有序列表,定义列表. 观察常用网页的HTML元素,在实际的应用场景中,用已学的标签模仿制作. <!DOCTYP ...

  4. Extjs4前端开发代码规范参考

    准则:  一致性, 隔离与统一管理, 螺旋式重构改进, 消除重复, 借鉴现有方案 1.    保证系统实现的一致性,寻求一致性方案, 相同或相似功能尽量用统一模式处理: 2.    尽可能使用隔离技术 ...

  5. Java重排序

    重排序数据依赖性 如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性.数据依赖分下列三种类型: 名称 代码示例 说明 写后读 a = 1;b = a; 写一个 ...

  6. 以太坊客户端Ethereum Wallet与Geth区别简介

    以太坊客户端Ethereum Wallet与Geth区别简介 最近有不少朋友在搭建交易平台,在咨询和技术交流的过程中发现很多朋友不太清楚Ethereum Wallet和Geth区别.甚至有朋友使用Ge ...

  7. 51Nod 1049 最大子段和

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1049 #include<iostream> #i ...

  8. 听 Fabien Potencier 谈Symfony2 之 《What is Symfony2 ?》

    Symfoy2 是什么? PHP世界里又一广受关注的web MVC框架? Fabien Potencier 却不这么说! Fabien Potencier这样定义Symfoy2 是个什么东西: 首先, ...

  9. How to use Nissan consult 3 plus to check, make key and program?

    How to use Nissan consult 3 plus to test Nissan? Firstly: get one particular Nissan consult 3 plus. ...

  10. Python基础教程之udp和tcp协议介绍

    Python基础教程之udp和tcp协议介绍 UDP介绍 UDP --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议.UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但 ...