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,如果这个骑士的战斗力超过了这个门槛,他就会根据城 ...
随机推荐
- 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 ...
- Mysql Federated For Windows
[1]windows环境下打开federated (1)关闭.命令:mysql> net stop mysql (2)添加federated字段.在my.ini文件中添加一个字段,注意位于[my ...
- vue-cli 脚手架搭建
1,下载node.js node.js 集成npm 管理器 2,打开命令行工具(win+R) node -v npm -v 出现对应版本号,则安装完成 3,配置代理信息 详见代理设定:https:// ...
- 设计模式之State(状态)(转)
State的定义: 不同的状态,不同的行为;或者说,每个状态有着相应的行为. 何时使用? State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif ...
- linux java -version 和 javac -version 不一致
我是在6 的基础上又装了一个 8. 结果java -v 和 javac -v的 一个显示 6 一个显示8 解决方式: 再次source 一下配置文件 如: source ~/.bashrc 或者 ...
- centos 6.8操作系统安装arcgis server 10.4
1.检查操作系统中软件包的安装,第一条和第二条是图形界面工具,可以不装. 可以用rpm -qa | grep 软件名 命令检查软件包是否已经安装 主机名不能包含下划线,可以用hostname检查主 ...
- 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 ...
- Integer诡异特性
package 代码测试; public class ceshi { public static void main(String[] args) { Integer i1=100; Integer ...
- 记账本微信小程序开发三
一.制作登陆界面: 更改全局配置,改颜色,名称: 界面 格式 登录界面 二.页面的跳转 按钮的设置 注册事件 结果
- 瀑布流之ajax
wf_js.html(展示页) <!DOCTYPE html> <html> <head> <meta charset="utf-8" / ...