题意:

给出一个n个结点的有根树,和m个骑士;

树上的结点——城池有一个防御值,骑士有一个战斗力;

当骑士的战斗力大于等于城池时,城池被攻破。骑士的战斗力变化,并向树上的父节点前进;

否则骑士死亡。

求最后每一个城池干掉的人数和每一个人干掉的城数;

骑士之间没有先后关系,就是说事实上每一个骑士是在自己的副本里战斗(笑)。

n,m<=300000。

题解:

首先依据战斗力变化的规则,从某个结点出发,战斗力弱的能到达哪里,战斗力强的也一定能够。

所以考虑一个结点上的所有骑士。仅仅须要比較防御值和最蒟蒻的骑士的战斗力就能够了。

他过不去就把他干掉比較下一个。过去了全部人就都过去了;

这实际上就像一个堆的模型了,仅仅是另一些问题要处理;

一是树形的结构。这个用拓扑排序能够搞定;

然后是树上各点间的转移,显然是要把几个结点的人集合起来,也就是堆的合并;

还有战斗力改变的处理,这里用能够打标记的左偏堆实现(当然左撇子右偏堆也能够啊XD)

之后就是码代码调试了。。

。Pushdown写挂一发。标记没开longlong一发,%I64d一发;

当年省选暴力写炸了= =,似乎是乱搞读入优化的锅咯;

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 310000
#define lson a[a[x].l]
#define rson a[a[x].r]
using namespace std;
typedef long long ll;
struct node
{
int l,r,dis,pos,cnt,c_cnt;
ll cadd,cmul,val;
}a[N];
ll h[N],v[N];
int f[N],out[N],tree[N];
int ans_of_knight[N],ans_of_city[N];
int q[N],st,en;
bool t[N];
void Pushdown(int x)
{
if(a[x].c_cnt)
{
lson.cnt+=a[x].c_cnt;
rson.cnt+=a[x].c_cnt;
lson.c_cnt+=a[x].c_cnt;
rson.c_cnt+=a[x].c_cnt;
a[x].c_cnt=0;
}
if(a[x].cmul!=1)
{
lson.val*=a[x].cmul;
rson.val*=a[x].cmul;
lson.cadd*=a[x].cmul;
rson.cadd*=a[x].cmul;
lson.cmul*=a[x].cmul;
rson.cmul*=a[x].cmul;
a[x].cmul=1;
}
if(a[x].cadd)
{
lson.val+=a[x].cadd;
rson.val+=a[x].cadd;
lson.cadd+=a[x].cadd;
rson.cadd+=a[x].cadd;
a[x].cadd=0;
}
}
int merge(int x,int y)
{
if(!x||!y) return x? x:y;
if(a[x].val>a[y].val)
swap(x,y);
Pushdown(x);
a[x].r=merge(a[x].r,y);
if(lson.dis<rson.dis)
swap(a[x].l,a[x].r);
a[x].dis=rson.dis+1;
return x;
}
void update(int x)
{
int root=tree[x];
a[root].c_cnt++;
a[root].cnt++;
if(t[x])
{
a[root].cmul*=v[x];
a[root].cadd*=v[x];
a[root].val*=v[x];
}
else
{
a[root].cadd+=v[x];
a[root].val+=v[x];
}
}
int main()
{
int n,m,i,j,k,x,y;
ll temp;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%lld",h+i);
for(i=2;i<=n;i++)
{
scanf("%d%d%lld",f+i,t+i,v+i);
out[f[i]]++;
}
a[0].dis=-1;
for(i=1;i<=m;i++)
{
scanf("%lld%d",&temp,&x);
a[i].pos=i,a[i].val=temp,a[i].cmul=1;
tree[x]=merge(tree[x],i);
}
st=1,en=0;
for(i=1;i<=n;i++)
{
if(!out[i])
q[++en]=i;
}
while(st<=en)
{
x=q[st++];
while(h[x]>a[tree[x]].val&&tree[x])
{
ans_of_city[x]++;
ans_of_knight[a[tree[x]].pos]=a[tree[x]].cnt;
Pushdown(tree[x]);
tree[x]=merge(a[tree[x]].l,a[tree[x]].r);
}
update(x);
tree[f[x]]=merge(tree[f[x]],tree[x]);
out[f[x]]--;
if(!out[f[x]])
q[++en]=f[x];
}
while(tree[0])
{
ans_of_knight[a[tree[0]].pos]=a[tree[0]].cnt;
Pushdown(tree[0]);
tree[0]=merge(a[tree[0]].l,a[tree[0]].r);
}
for(i=1;i<=n;i++)
printf("%d\n",ans_of_city[i]);
for(i=1;i<=m;i++)
printf("%d\n",ans_of_knight[i]);
return 0;
}

bzoj-4003 城池攻占的更多相关文章

  1. bzoj 4003: 城池攻占 左偏树

    题目大意 http://www.lydsy.com/JudgeOnline/problem.php?id=4003 题解 一开始看漏条件了 题目保证当占领城池可以使攻击力乘上\(v_i\)时,一定有\ ...

  2. 【BZOJ】【4003】【JLOI2015】城池攻占

    可并堆 QAQ改了一下午……最终弃疗求助zyf……居然被秒了QAQ真是弱到不行(zyf太神了Orz) 还是先考虑部分分的做法: 1.$n,m\leq 3000$:可以暴力模拟每个骑士的攻打过程,也可以 ...

  3. Luogu 3261 [JLOI2015]城池攻占

    BZOJ 4003 需要实现一个可并堆. 每个点维护一个小根堆,然后一开始把所有骑士加入到它所在的点的小根堆当中,实际上空间是$O(m)$的,然后我们从上到下不断合并这个小根堆,合并完之后如果遇到堆顶 ...

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

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

  5. 「JLOI2015」城池攻占 解题报告

    「JLOI2015」城池攻占 注意到任意两个人的战斗力相对大小的不变的 可以离线的把所有人赛到初始点的堆里 然后做启发式合并就可以了 Code: #include <cstdio> #in ...

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

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

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

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

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

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

  9. BZOJ 4003 【JLOI2015】城池攻占

    Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖, ...

  10. BZOJ 4003: [JLOI2015]城池攻占 左偏树 可并堆

    https://www.lydsy.com/JudgeOnline/problem.php?id=4003 感觉就是……普通的堆啊(暴论),因为这个堆是通过递归往右堆里加一个新堆或者新节点的,所以要始 ...

随机推荐

  1. Apache Thrift使用简介

    Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架.和其它RPC框架相比,它主要具有如下连个特点: 高性能. 它采用的是二进制序列化,并且用的是长 ...

  2. 升压转换器 (Boost)

    升压转换器 (Boost) 需要将输入电压转换为较高的输出电压时,升压转换器 (Boost)是唯一的选择. 升压转换器透过内部 MOSFET 对电压充电来达成升压输出的目的,而当 MOSFET 关闭时 ...

  3. 在Mac中设置Ctrl+C/V进行复制/粘贴

    从Windows世界走入Mac世界,最让不习惯的是在Mac中“复制/粘贴”的快捷键是Command+C/V.而且Command键与C/V键靠得太近,只能用大拇指与食指进行操作,也让人不习惯.再加上远程 ...

  4. 【spring】在spring cloud项目中使用@ControllerAdvice做自定义异常拦截,无效 解决原因

    之前在spring boot服务中使用@ControllerAdvice做自定义异常拦截,完全没有问题!!! GitHub源码地址: 但是现在在spring cloud中使用@ControllerAd ...

  5. FAQ:领域服务和应用服务的职责是什么?

    问答部分 问: 领域服务的职责是什么? 答: 夸聚合实例业务逻辑. 没办法合理放到实体中的其它业务逻辑. 问: 领域服务的设计原则是什么? 答: 用来组织业务逻辑. 面向业务逻辑. 细粒度. 内部视图 ...

  6. go语言基础之多个defer执行顺序

    1. 多个defer执行顺序 如果一个函数中有多个defer语句,它们会以LIFO(后进先出)的顺序执行.哪怕函数或某个延迟调用发生错误,这些调用依旧会被执.示例: package main //必须 ...

  7. Iometer教程

    Iometer Tutorial and Introduction http://www.itechstorm.com/iometer-tutorial-introduction

  8. 【React】初识React

    React是什么 React是如今(2015年)最热门的前端技术. 在React中.一切皆组件. A JavaScript library for building user interfaces R ...

  9. authpuppy 认证服务器搭建

    此文仅限于搭建authpuppy认证服务器,不包含认证插件等安装,仅说明步骤以备下次安装忘记步骤.耽误时间. 环境:ubuntu10.04 软件版本:authpuppy-1.0.0-stable.tg ...

  10. Dubbo之旅--集群容错和负载均衡

    当我们的系统中用到Dubbo的集群环境,由于各种原因在集群调用失败时,Dubbo提供了多种容错方案,缺省为failover重试. Dubbo的集群容错在这里想说说他是由于我们实际的项目中出现了此类的问 ...