Description

It's milking time at Farmer John's farm, but the cows have all run away! Farmer John needs to round them all up, and needs your help in the search.

FJ's farm is a series of N (1 <= N <= 200,000) pastures numbered 1...N connected by N - 1 bidirectional paths. The barn is located at pasture 1, and it is possible to reach any pasture from the barn.

FJ's cows were in their pastures this morning, but who knows where they ran to by now. FJ does know that the cows only run away from the barn, and they are too lazy to run a distance of more than L. For every pasture, FJ wants to know how many different pastures cows starting in that pasture could have ended up in.

Note: 64-bit integers (int64 in Pascal, long long in C/C++ and long in Java) are needed to store the distance values.

给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个。

Input

  • Line 1: 2 integers, N and L (1 <= N <= 200,000, 1 <= L <= 10^18)

  • Lines 2..N: The ith line contains two integers p_i and l_i. p_i (1 <= p_i < i) is the first pasture on the shortest path between pasture i and the barn, and l_i (1 <= l_i <= 10^12) is the length of that path.

Output

  • Lines 1..N: One number per line, the number on line i is the number pastures that can be reached from pasture i by taking roads that lead strictly farther away from the barn (pasture 1) whose total length does not exceed L.

Sample Input

4 5
1 4
2 3
1 5

Sample Output

3
2
1
1

Hint

Cows from pasture 1 can hide at pastures 1, 2, and 4.

Cows from pasture 2 can hide at pastures 2 and 3.

Pasture 3 and 4 are as far from the barn as possible, and the cows can hide there.

题解

简要来说,左偏树

具体思想是:先$Dfs$求出根节点到各个节点的距离,再按逆$Dfs$时间戳顺序进行操作(为了使得处理的当前节点的所有子节点均被处理过,至于为何不正向,就不解释了)

建大根堆,每次做完合并操作后,将不可行的边从堆中弹出(即堆顶所表示的点到当前点的距离$>L$(同时以操作顺序为前提的条件下必有“相距距离=两点到根节点的距离差”))

另一个需要解决的问题就是如何求解,我们可以按逆$Dfs$序模拟一个回溯过程:将所以$pop$掉的值和其子节点的值累加,再相减即可。

 #include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const long long N=;
struct tt
{
long long cost,next,to;
}edge[*N+];//保存边的信息
long long path[N+],top;
struct node
{
long long key,dist;
node *l,*r;
long long ldist() {return l ? l->dist:-;}
long long rdist() {return r ? r->dist:-;}
}T[N+],*root[N+];//T[i]表示节点i的相关信息;root[i]表示序号为i的节点所在堆的根的地址
long long n,l,a,b;
long long remain[N+],tail,Rank[N+];//remain[]表示逆Dfs顺序,tail表示remain[]的大小;Rank[]表示Bfs序
long long popnum[N+],cnt[N+];//popnum[i]保存在i节点时,弹出元素的数量 cnt[i]表示以i为根,其子树节点数量(不含根节点)
void Add(long long x,long long y,long long cost);
void Dfs(long long x);
node* Merge(node* a,node* b);
int main()
{
scanf("%lld%lld",&n,&l);
for (long long i=;i<=n;i++)
{
scanf("%lld%lld",&a,&b);
Add(a,i,b);
Add(i,a,b); }//连双向边,正向用于Dfs用,逆向用于求解用 Rank[]=;
Dfs();
for (long long i=;i<=tail;i++)
{
for (long long j=path[remain[i]];j;j=edge[j].next)
{
if (Rank[remain[i]]==Rank[edge[j].to]+)//找到前驱节点
{
root[edge[j].to]=Merge(root[remain[i]],root[edge[j].to]);//将当前节点构成的堆并入前驱节点
while(root[edge[j].to]->key-T[edge[j].to].key>l)//弹出
{
popnum[edge[j].to]++;
root[edge[j].to]=Merge(root[edge[j].to]->l,root[edge[j].to]->r);
}
}
}
}
for (long long i=;i<=tail;i++) //对最终答案数据的处理
{
for (long long j=path[remain[i]];j;j=edge[j].next)
{
if (Rank[remain[i]]==Rank[edge[j].to]+)
{
cnt[edge[j].to]+=cnt[remain[i]]+;
popnum[edge[j].to]+=popnum[remain[i]];
}
}
}
for (long long i=;i<=n;i++) printf("%lld\n",cnt[i]+-popnum[i]);
return ;
}
void Add(long long x,long long y,long long cost)
{
edge[++top].to=y;
edge[top].cost=cost;
edge[top].next=path[x];
path[x]=top;
}
void Dfs(long long x)
{
root[x]=x+T;
for (long long i=path[x];i;i=edge[i].next) if (!Rank[edge[i].to])
{
Rank[edge[i].to]=Rank[x]+;
T[edge[i].to].key=T[x].key+edge[i].cost;//key保存的是根节点到该点的距离
Dfs(edge[i].to);
}
remain[++tail]=x;
}
node* Merge(node* a,node* b)
{
if (!a||!b) return a ? a:b;
if (a->key<b->key) swap(a,b);
a->r=Merge(a->r,b);
if (a->ldist()<a->rdist()) swap(a->l,a->r);
a->dist=a->rdist()+;
return a;
}

[USACO 12DEC]Running Away From the Barn的更多相关文章

  1. BZOJ 3011: [Usaco2012 Dec]Running Away From the Barn( dfs序 + 主席树 )

    子树操作, dfs序即可.然后计算<=L就直接在可持久化线段树上查询 -------------------------------------------------------------- ...

  2. BZOJ_3011_[Usaco2012 Dec]Running Away From the Barn _可并堆

    BZOJ_3011_[Usaco2012 Dec]Running Away From the Barn _可并堆 Description 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于l的 ...

  3. 【BZOJ3011】[Usaco2012 Dec]Running Away From the Barn 可并堆

    [BZOJ3011][Usaco2012 Dec]Running Away From the Barn Description It's milking time at Farmer John's f ...

  4. USACO Running Away From the Barn /// 可并堆 左偏树维护大顶堆

    题目大意: 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于m的点有多少个 左偏树 https://blog.csdn.net/pengwill97/article/details/82 ...

  5. [Usaco2012 Dec]Running Away From the Barn

    题目描述 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个. 输入格式 Line 1: 2 integers, N and L (1 <= N <= 200,0 ...

  6. [BZOJ3011][Usaco2012 Dec]Running Away From the Barn

    题意 给出一棵以1为根节点树,求每个节点的子树中到该节点距离<=l的节点的个数 题解 方法1:倍增+差分数组 首先可以很容易的转化问题,考虑每个节点对哪些节点有贡献 即每次对于一个节点,找到其第 ...

  7. USACO 2008 Running(贝茜的晨练)

    [题解] 动态规划,dp[i][j]表示第i分钟疲劳度为j的最长距离. [代码] #include <iostream> #include <cstdlib> #include ...

  8. 洛谷P1353 USACO 跑步 Running

    题目 一道入门的dp,首先要先看懂题目要求. 容易得出状态\(dp[i][j]\)定义为i时间疲劳度为j所得到的最大距离 有两个坑点,首先疲劳到0仍然可以继续疲劳. 有第一个方程: \(dp[i][0 ...

  9. bzoj3011 [Usaco2012 Dec]Running Away From the Barn 左偏树

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3011 题解 复习一下左偏树板子. 看完题目就知道是左偏树了. 结果这个板子还调了好久. 大概已 ...

随机推荐

  1. Struts2学习笔记二 配置详解

    Struts2执行流程 1.简单执行流程,如下所示: 在浏览器输入请求地址,首先会被过滤器处理,然后查找主配置文件,然后根据地址栏中输入的/hello去每个package中查找为/hello的name ...

  2. 计算1-1/3+1/5-1/7+···的前n项和

    这图1为书里的教材,图二为自己打的程序 (1)二者相比,自己写的代码显得更短,听说代码写的越精简越好,但是自己的较难分析,他人看来可能会较难理解一点:(自己在第一次运行时将for()中的第二个表达式写 ...

  3. Java虚拟机16:Metaspace

    被废弃的持久代 想起之前面试的时候有面试官问起过我一个问题:Java 8为什么要废弃持久代即Metaspace的作用.由于当时使用的Java 7且研究重心不在JVM上,一下没有回答上来,今天突然想起这 ...

  4. 关于5303狄惟佳同学的myod程序设计的补充实现

    关于5303狄惟佳同学的myod程序设计的补充实现 原版代码实现的局限 原版代码主函数 int main(int argc,char *argv[]) { if(strcmp(argv[1], &qu ...

  5. Alpha冲刺Day9

    Alpha冲刺Day9 一:站立式会议 今日安排: 经过为期5天的冲刺,基本完成企业人员模块的开发.因第三方机构与企业存在委托的关系.第三方人员对于风险的自查.风险列表的展示以及自查风险的统计展示(包 ...

  6. 201621123031 《Java程序设计》第9周学习总结

    作业09-集合与泛型 1.本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 一.泛型的基本概念 泛型是JDK 1.5的一项新特性,它的本质是参数化类型(Paramet ...

  7. python的迭代器、生成器、装饰器

    迭代器.生成器.装饰器 在这个实验里我们学习迭代器.生成器.装饰器有关知识. 知识点 迭代器 生成器 生成器表达式 闭包 装饰器 实验步骤 1. 迭代器 Python 迭代器(Iterators)对象 ...

  8. Beta冲刺Day3

    项目进展 李明皇 今天解决的进度 完善了程序的运行逻辑(消息提示框等) 明天安排 前后端联动调试 林翔 今天解决的进度 向微信官方申请登录验证session以维护登录态 明天安排 继续完成维护登录态 ...

  9. 日志 --BUG记录

    2014-12-15日 在做520wawa的免费推广   部署web应用时 错把path设置为"/*",导致启动tomcat时,导致错误 <Context path=&quo ...

  10. JAVA的循环控制与循环嵌套

    循环控制和循环嵌套 循环控制是除了循环条件之外,控制循环是否进行的一个机制,这给处理循环问题带来了灵活性.循环体内的语句块可以是顺序执行的语句,可以是分支结构的语句,也可以是循环语句,循环中含循环,就 ...