思路

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

注意做乘法的时候加法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. D Tree Requests dfs+二分 D Pig and Palindromes -dp

    D time limit per test 2 seconds memory limit per test 256 megabytes input standard input output stan ...

  2. Mysql Federated For Windows

    [1]windows环境下打开federated (1)关闭.命令:mysql> net stop mysql (2)添加federated字段.在my.ini文件中添加一个字段,注意位于[my ...

  3. vue-cli 脚手架搭建

    1,下载node.js node.js 集成npm 管理器 2,打开命令行工具(win+R) node -v npm -v 出现对应版本号,则安装完成 3,配置代理信息 详见代理设定:https:// ...

  4. 设计模式之State(状态)(转)

    State的定义: 不同的状态,不同的行为;或者说,每个状态有着相应的行为. 何时使用? State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif ...

  5. linux java -version 和 javac -version 不一致

    我是在6 的基础上又装了一个 8. 结果java -v 和 javac -v的 一个显示 6 一个显示8 解决方式: 再次source 一下配置文件 如: source ~/.bashrc   或者  ...

  6. centos 6.8操作系统安装arcgis server 10.4

    1.检查操作系统中软件包的安装,第一条和第二条是图形界面工具,可以不装. 可以用rpm -qa | grep 软件名   命令检查软件包是否已经安装 主机名不能包含下划线,可以用hostname检查主 ...

  7. AURO OtoSys IM100 vs Lonsdor K518ISE: which better?

    Comparison: AURO OtoSys IM100 and Lonsdor K518ISE It’s aimed to help make a purchase of decent auto ...

  8. Integer诡异特性

    package 代码测试; public class ceshi { public static void main(String[] args) { Integer i1=100; Integer ...

  9. 记账本微信小程序开发三

    一.制作登陆界面: 更改全局配置,改颜色,名称: 界面 格式 登录界面 二.页面的跳转 按钮的设置 注册事件 结果

  10. 瀑布流之ajax

    wf_js.html(展示页) <!DOCTYPE html> <html> <head> <meta charset="utf-8" / ...