题目描述

小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池。这 n 个城池用 1 到 n 的整数表示。除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖,其中 fi <i。也就是说,所有城池构成了一棵有根树。这 m 个骑士用 1 到 m 的整数表示,其中第 i 个骑士的初始战斗力为 si,第一个攻击的城池为 ci。

每个城池有一个防御值 hi,如果一个骑士的战斗力大于等于城池的生命值,那么骑士就可以占领这座城池;否则占领失败,骑士将在这座城池牺牲。占领一个城池以后,骑士的战斗力将发生变化,然后继续攻击管辖这座城池的城池,直到占领 1 号城池,或牺牲为止。

除 1 号城池外,每个城池 i 会给出一个战斗力变化参数 ai;vi。若 ai =0,攻占城池 i 以后骑士战斗力会增加 vi;若 ai =1,攻占城池 i 以后,战斗力会乘以 vi。注意每个骑士是单独计算的。也就是说一个骑士攻击一座城池,不管结果如何,均不会影响其他骑士攻击这座城池的结果。

现在的问题是,对于每个城池,输出有多少个骑士在这里牺牲;对于每个骑士,输出他攻占的城池数量。

在每个节点给骑士挂链,每次合并上来后把所有子树中攻击力小于城市防御力的骑士弹掉。加乘用懒标记。

pay attention to:

1、在进行每一操作时要检查那个堆是不是空的,若是即return;

2、乘时加标记也要乘;

3、在进行每一操作时要Pushdown;

4、注意到dfs开始时A赋值为0,这是因为若赋值为u则默认u骑士在u节点,前面“派遣”等赋值为u正因此。
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
const int N=3e5+100;
ll n,m,D[N],v[N],F[N],plu[N],mul[N];
int h[N],cnt,ls[N],rs[N],ft[N],st[N],d[N],die[N],a[N],dis[N],k[N];
struct Edge
{
  int to,next;
}e[N];
struct edge
{
  int to,next;
}q[N];
il void add(re int u,re int v)
{
  e[++cnt]=(Edge){v,h[u]};h[u]=cnt;
}
il ll gi()
{
  re ll x=0,t=1;
  re char ch=getchar();
  while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
  if(ch=='-') t=-1,ch=getchar();
  while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  return x*t;
}
il void work(re int A,re ll jia,re ll che)
{
  if(!A) return;//干啥都要注意是否为空堆
  F[A]*=che;F[A]+=jia;
  plu[A]*=che;plu[A]+=jia;mul[A]*=che;//乘时加标记也要乘
}
il void Pushdown(re int A)
{
  work(ls[A],plu[A],mul[A]);
  work(rs[A],plu[A],mul[A]);
  plu[A]=0;mul[A]=1;
}
il int Merge(re int A,re int B)
{
  if(!A||!B) return A+B;
  Pushdown(A);Pushdown(B);//无处不Pushdown
  if(F[A]>F[B]) swap(A,B);
  rs[A]=Merge(rs[A],B);
  if(dis[ls[A]]<dis[rs[A]]) swap(ls[A],rs[A]);
  dis[A]=dis[rs[A]]+1;
  return A;
}
il int Delete(re int A)
{
  Pushdown(A);
  return Merge(ls[A],rs[A]);
}
il int dfs(re int u,re int deep)
{
  re int A=0;//
  d[u]=deep;
  for(re int i=ft[u];i;i=q[i].next)
    {
      re int v=q[i].to;
      A=Merge(A,v);//每个骑士构出一条链来
    }
  for(re int i=h[u];i;i=e[i].next)
    {
      re int v=e[i].to;
      A=Merge(A,dfs(v,deep+1));
    }
  while(F[A]<D[u]&&A) k[A]=u,++die[u],A=Delete(A);
  if(a[u]) work(A,0,v[u]);else work(A,v[u],1);
  return A;
}
int main()
{
  n=gi();m=gi();
  fp(i,1,n) D[i]=gi();
  fp(i,2,n)
    {
      re int u=gi();a[i]=gi(),v[i]=gi();
      add(u,i);
    }
  cnt=0;
  fp(i,1,m)
    {
      F[i]=gi();st[i]=gi();
      q[++cnt]=(edge){i,ft[st[i]]};ft[st[i]]=cnt;
    }
  dfs(1,1);
  fp(i,1,n) printf("%d\n",die[i]);
  fp(i,1,m) printf("%d\n",d[st[i]]-d[k[i]]);
  return 0;
}

LuoguP3261 [JLOI2015]城池攻占的更多相关文章

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

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

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

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

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

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

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

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

  5. [JLOI2015]城池攻占

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

  6. [JLOI2015]城池攻占 左偏树

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

  7. BZOJ4003[JLOI2015]城池攻占——可并堆

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

  8. BZOJ4003 [JLOI2015]城池攻占 左偏树 可并堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4003 题意概括 题意有点复杂,直接放原题了. 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑 ...

  9. 【左偏树】【P3261】 [JLOI2015]城池攻占

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

随机推荐

  1. 第二节:SQLServer导出-重置sa密码-常用sql语句

    1.SQLServer导出: 点击要导出数据库----->右键(任务)----->生成脚本----->下一步----->下一步(高级)要编写脚本的数据类型---选择架构和数据 ...

  2. 解决docker容器启动时候无法映射端口的问题

    当我们停止防火墙后,docker容器启动映射端口可能无法映射端口,这个时候需要重建docker0网桥. 详细的错误是这样的: docker: Error response from daemon: d ...

  3. OpenCV+Python识别车牌和字符分割的实现

    本篇文章主要基于python语言和OpenCV库(cv2)进行车牌区域识别和字符分割,开篇之前针对在python中安装opencv的环境这里不做介绍,可以自行安装配置! 车牌号检测需要大致分为四个部分 ...

  4. session 分布式处理-----https://segmentfault.com/a/1190000013447750?utm_source=tag-newest

    第一种:粘性session 粘性Session是指将用户锁定到某一个服务器上,比如上面说的例子,用户第一次请求时,负载均衡器将用户的请求转发到了A服务器上,如果负载均衡器设置了粘性Session的话, ...

  5. Bellman-ford算法的学习http://blog.csdn.net/niushuai666/article/details/6791765

    http://blog.csdn.net/niushuai666/article/details/6791765

  6. 【POJ3159】Candies(差分约束系统)

    题意:有一些人, 给n个人派糖果,给出m组约束,每组约束包含A,B,c 三个数, 意思是A的糖果数比B少的个数不多于c,即B的糖果数 - A的糖果数<= c . 最后求n 比 1 最多多多少糖果 ...

  7. CODEVS1222 信与信封问题 (匈牙利算法)

    先做一遍匈牙利算法.对于已经匹配的边,如果删去之后还能最大匹配数增加,则不符合要求. 一遍匈牙利算法是O(n^3)的,对于每一条边做n次,每次O(n^2),总的复杂度是O(n^3). 注意:不要忘记输 ...

  8. C. Painting Fence 分治

    memory limit per test 512 megabytes input standard input output standard output Bizon the Champion i ...

  9. Spring——ClassPathXmlApplicationContext(配置文件路径解析 1)

    ClassPathXmlApplicationContext     在我的 BeanFactory 容器文章中主要提及了 BeanFactory 容器初始化(Spring 配置文件加载(还没解析)) ...

  10. 只用html和css画出不等分圆盘,不用canvas

    <style> .box{height: 200px;width: 200px;border-radius: 100%; overflow: hidden; margin: 200px; ...