题解 USACO12DEC【逃跑的BarnRunning Away From…】
期末考前写题解,\(rp++! \ rp++! \ rp++!\)
\]
给出一个以 \(1\) 为根的边带权有根树,给定一个参数 \(L\) ,问每个点的子树中与它距离小于等于 \(L\) 的节点个数。
\]
有关子树内的统计,肯定能联想到 线段树合并 吧。
记 \(d[u]\) 表示根节点到 \(u\) 的距离,该数组可通过一次遍历求出。
则对于每个点 \(u\) ,它的贡献就是满足下式的点对数量:
\]
移项,可化简为:
\]
那么问题就转化成了:
令点 \(u\) 的点权为 \(d[u]\)。对于每个点 \(u\) ,求出该点的子树中点权小于等于 \(d[u]+L\) 的节点个数
然后发现是一道 线段树合并 板子题,直接码上就行。
需注意的是,这个 \(L\) 和 \(d[~]\) 的范围有 \(1e18\) ,所以我们需要离散化一下防止 \(MLE\) 。
我是把每个 \(d[u]\) 以及 \(d[u]+L\) 都扔进去离散化了,如果有哪位 \(dalao\) 有更优秀的离散化方法,可以评论在博客下方,我会感激不尽。
\]
#include<cstdio>
#include<algorithm>
#define RI register int
using namespace std;
const int N=200100,M=200100,MLOGN=10001000;
int n,m;
long long L;
int Etot,head[N],ver[M],Next[M];
long long edge[M];
void add(int u,int v,long long w)
{
ver[++Etot]=v; edge[Etot]=w; Next[Etot]=head[u]; head[u]=Etot;
}
long long d[N];
int len;
long long mapval[1000100];
void discrete()
{
sort(mapval+1,mapval+1+len);
len=unique(mapval+1,mapval+1+len)-mapval-1;
}
int query(long long x)
{
return lower_bound(mapval+1,mapval+1+len,x)-mapval;
}
int tot,root[N];
struct SegmentTree{
int lc,rc;
int cnt;
}t[MLOGN];
int New()
{
tot++;
t[tot].lc=t[tot].rc=t[tot].cnt=0;
return tot;
}
void insert(int &p,int l,int r,int delta,int val)
{
if(!p)p=New();
t[p].cnt+=val;
if(l==r)return;
int mid=(l+r)/2;
if(delta<=mid)
insert(t[p].lc,l,mid,delta,val);
else
insert(t[p].rc,mid+1,r,delta,val);
}
int merge(int p,int q)
{
if(!p||!q)return p^q;
t[p].cnt+=t[q].cnt;
t[p].lc=merge(t[p].lc,t[q].lc);
t[p].rc=merge(t[p].rc,t[q].rc);
return p;
}
int ask(int p,int l,int r,int s,int e)
{
if(!p)return 0;
if(s<=l&&r<=e)return t[p].cnt;
int mid=(l+r)/2;
int val=0;
if(s<=mid)
val+=ask(t[p].lc,l,mid,s,e);
if(mid<e)
val+=ask(t[p].rc,mid+1,r,s,e);
return val;
}
void dfs1(int u)
{
mapval[++len]=d[u],mapval[++len]=d[u]+L;
for(RI i=head[u];i;i=Next[i])
{
int v=ver[i];
long long w=edge[i];
d[v]=d[u]+w;
dfs1(v);
}
}
int ans[N];
void dfs2(int u)
{
for(RI i=head[u];i;i=Next[i])
{
int v=ver[i];
dfs2(v);
root[u]=merge(root[u],root[v]);
}
insert(root[u],1,len,query(d[u]),1);
ans[u]=ask(root[u],1,len,1,query(d[u]+L));
}
int main()
{
scanf("%d%lld",&n,&L);
for(RI i=2;i<=n;i++)
{
int fa;
long long w;
scanf("%d%lld",&fa,&w);
add(fa,i,w);
}
dfs1(1);
discrete();
dfs2(1);
for(RI i=1;i<=n;i++)
printf("%d\n",ans[i]);
return 0;
}
\]
题解 USACO12DEC【逃跑的BarnRunning Away From…】的更多相关文章
- [USACO12DEC] 逃跑的BarnRunning Away From…(主席树)
[USACO12DEC]逃跑的BarnRunning Away From- 题目描述 It's milking time at Farmer John's farm, but the cows hav ...
- luoguP3066 [USACO12DEC]逃跑的BarnRunning
luoguP3066 [USACO12DEC]逃跑的BarnRunning 题目大意 给定一棵n个节点的树和参数L,查询每个节点子树中到达该节点距离<=L的数量(包括该节点) 偏模板的主席树 P ...
- [Luogu3066][USACO12DEC]逃跑的BarnRunning Away From…
题面 题目描述 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个. 输入格式: Line 1: 2 integers, N and L (1 <= N <= 2 ...
- 洛谷P3066 [USACO12DEC]逃跑的BarnRunning Away From…
题面链接 一句话题意:给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个. 我:似乎并不好做啊...看了题解后大雾... sol:考虑树上差分,对于一个点,在他那个位置++, ...
- [USACO12DEC]逃跑的BarnRunning Away From…
题意 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个 题解 似乎有好多种做法啊……然而蒟蒻只会打打主席树的板子…… 调了一个上午一直WA……狠下心来重打一遍居然直接一遍过 ...
- P3066 [USACO12DEC]逃跑的BarnRunning Away From
目录 题目 思路 错误&&注意 代码 题目 luoguP3066 思路 虽说这个题目有多种做法,但 左偏树算法: 我们发现这个合并的时候并不好合并,因为存的值不是固定的 那我们是不是可 ...
- Luogu 3066 [USACO12DEC]逃跑的BarnRunning Away From…
好像是某CF的题,不记得…… 很套路的题,但是觉得可以做一下笔记. 倍增 + 差分. 有一个比较简单的思路就是每一个点$x$向上走一走,直到走到一个点$y$使总路程恰好不超过超过了$L$,然后把$(x ...
- P3066 [USACO12DEC]逃跑的BarnRunning Away From (树上二分)
题意 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个. 树上二分.这个做法还是基于树上差分的,也就是对于每一个点uu,我们要找到它向上跳LL的长度最高能够跳到的祖先.(当 ...
- P3066 [USACO12DEC]逃跑的BarnRunning Away From… 树上差分_树上倍增
code: #include <cstdio> using namespace std; #define ll long long const int N=200005; int n,fa ...
随机推荐
- Django常用字段及参数、事务、数据库查询优化
常用字段 注意: Django中没有设置对应char类型的字段,但可以支持自己定义. 自定义对应于数据库的char类型字段: from django.db.models import Field cl ...
- 【转】7本免费的Java电子书和教程
本文由 ImportNew - 唐小娟 翻译自 Javapapers.如需转载本文,请先参见文章末尾处的转载要求. 1. Thinking in Java (Third Edition) 本书的作者是 ...
- Codeforces - A. Watermelon
A. Watermelon time limit per test 1 second memory limit per test 64 megabytes input standard input o ...
- 为什么双击打开py文件时窗口瞬间关闭了?
当前理解,py文件里没有input() 等暂停程序运行的函数,程序运行速度太快,运行完就立马关闭了. input()调用后,程序会立即暂停,等待用户输入
- axios全局引用
在vue项目开发中,我们使用axios进行ajax请求,很多人一开始使用axios的方式,会当成vue-resoure的使用方式来用,即在主入口文件引入import VueResource from ...
- lisp学习总结(一)
lisp太简单 lisp核心太简单了只有几个简单的逻辑定理,简单到你会认为他啥事都做不了. lisp语法太简单了,只有符号,参数,以及括号,组成一种万能的表达式. 由于上述lisp的简单,所以对于初学 ...
- ASP.NET Cookie是怎么生成的
ASP.NET Cookie是怎么生成的 可能有人知道Cookie的生成由machineKey有关,machineKey用于决定Cookie生成的算法和密钥,并如果使用多台服务器做负载均衡时,必须指定 ...
- 20200104模拟赛 问题C 上台拿衣服
题目 分析: 乍一看不就是从楼上扔鸡蛋那道题吗... 然后开始写写写... 设f [ i ] [ j ]表示 i 个记者膜 j 次可以验证多少层楼... 于是开始递推: 我们选取第 i 个记者去尝试其 ...
- Scala 学习(6)之「对象」
目录 object 伴生对象 继承抽象类 apply方法 main方法 用 object 来实现枚举功能 object 相当于 class 的单个实例,通常在里面放一些静态的 field 或者 met ...
- Client API Object Model - Execution Context
1. executionContext. executionContext定义代码在其中执行的上下文. 并且适用在再form或者grid中的event handler. 比如formContext 或 ...