期末考前写题解,\(rp++! \ rp++! \ rp++!\)

\[description
\]

给出一个以 \(1\) 为根的边带权有根树,给定一个参数 \(L\) ,问每个点的子树中与它距离小于等于 \(L\) 的节点个数。

\[solution
\]

有关子树内的统计,肯定能联想到 线段树合并 吧。

记 \(d[u]\) 表示根节点到 \(u\) 的距离,该数组可通过一次遍历求出。

则对于每个点 \(u\) ,它的贡献就是满足下式的点对数量:

\[d[v]-d[u]\leq L \ \{ v\in\operatorname{subtree}(u) \}
\]

移项,可化简为:

\[d[v]\leq d[u]+L \ \{ v\in\operatorname{subtree}(u) \}
\]

那么问题就转化成了:

令点 \(u\) 的点权为 \(d[u]\)。对于每个点 \(u\) ,求出该点的子树中点权小于等于 \(d[u]+L\) 的节点个数

然后发现是一道 线段树合并 板子题,直接码上就行。

需注意的是,这个 \(L\) 和 \(d[~]\) 的范围有 \(1e18\) ,所以我们需要离散化一下防止 \(MLE\) 。

我是把每个 \(d[u]\) 以及 \(d[u]+L\) 都扔进去离散化了,如果有哪位 \(dalao\) 有更优秀的离散化方法,可以评论在博客下方,我会感激不尽。

\[code
\]

#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;
}

\[thanks \ for \ watching
\]

题解 USACO12DEC【逃跑的BarnRunning Away From…】的更多相关文章

  1. [USACO12DEC] 逃跑的BarnRunning Away From…(主席树)

    [USACO12DEC]逃跑的BarnRunning Away From- 题目描述 It's milking time at Farmer John's farm, but the cows hav ...

  2. luoguP3066 [USACO12DEC]逃跑的BarnRunning

    luoguP3066 [USACO12DEC]逃跑的BarnRunning 题目大意 给定一棵n个节点的树和参数L,查询每个节点子树中到达该节点距离<=L的数量(包括该节点) 偏模板的主席树 P ...

  3. [Luogu3066][USACO12DEC]逃跑的BarnRunning Away From…

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

  4. 洛谷P3066 [USACO12DEC]逃跑的BarnRunning Away From…

    题面链接 一句话题意:给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个. 我:似乎并不好做啊...看了题解后大雾... sol:考虑树上差分,对于一个点,在他那个位置++, ...

  5. [USACO12DEC]逃跑的BarnRunning Away From…

    题意 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个 题解 似乎有好多种做法啊……然而蒟蒻只会打打主席树的板子…… 调了一个上午一直WA……狠下心来重打一遍居然直接一遍过 ...

  6. P3066 [USACO12DEC]逃跑的BarnRunning Away From

    目录 题目 思路 错误&&注意 代码 题目 luoguP3066 思路 虽说这个题目有多种做法,但 左偏树算法: 我们发现这个合并的时候并不好合并,因为存的值不是固定的 那我们是不是可 ...

  7. Luogu 3066 [USACO12DEC]逃跑的BarnRunning Away From…

    好像是某CF的题,不记得…… 很套路的题,但是觉得可以做一下笔记. 倍增 + 差分. 有一个比较简单的思路就是每一个点$x$向上走一走,直到走到一个点$y$使总路程恰好不超过超过了$L$,然后把$(x ...

  8. P3066 [USACO12DEC]逃跑的BarnRunning Away From (树上二分)

    题意 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个. 树上二分.这个做法还是基于树上差分的,也就是对于每一个点uu,我们要找到它向上跳LL的长度最高能够跳到的祖先.(当 ...

  9. P3066 [USACO12DEC]逃跑的BarnRunning Away From… 树上差分_树上倍增

    code: #include <cstdio> using namespace std; #define ll long long const int N=200005; int n,fa ...

随机推荐

  1. Python在Windows下列出所有的安装包和模块

    1.查看python安装的module python -m pydoc module 或 >>>help('module') 2.用pip查看 pip list

  2. 递推 dp - 求有多少个序列符合题意

    题目描述     小美有一个由n个元素组成的序列{a1,a2,a3,...,an},她想知道其中有多少个子序列{ap1,ap2,...,apm}(1 ≤ m ≤ n, 1 ≤ p1 < p2 , ...

  3. 牛客网上的ST阶跃表

    给你一个长为n的序列a和一个常数k 有m次询问,每次查询一个区间[l,r]内所有数最少分成多少个连续段,使得每段的和都 <= k 如果这一次查询无解,输出"Chtholly" ...

  4. Nest.js你学不会系列-初识Nest

    前言 最近在学习研究 Nest 框架,但是在学习过程中除了参考翻阅官方文档外国内几乎没有多少资料能系统的讲解 Nest 的相关内容,所以打算想通过我自己学习的角度讲解下 Nest 框架,不知道能坚持多 ...

  5. Linux下安装Ant

    前言 Apache Ant 是一个构建工具,可以将软件编译.测试.部署等步骤联系在一起完成自动化工作,比如可以利用Ant来执行Jmeter的 jmx 脚本,生成了 jtl 测试结果文件,接着再利用An ...

  6. java.lang.UnsupportedOperationException: Manual close is not allowed over a Spring managed SqlSession

    java.lang.UnsupportedOperationException: Manual close is not allowed over a Spring managed SqlSessio ...

  7. shell 条件测试

    1.文件相关 -e 判断文件或者文件夹是否存在 -d 判断目录是否存在 -f 判断文件是否存在 -r 判断是否有读权限 -w 判断是否有写权限 -x 判断是否有执行权限 1.1命令行使用 [root@ ...

  8. python接口测试,mock模块基本使用介绍

    mock简介 py3已将mock集成到unittest库中 为的就是更好的进行单元测试 简单理解,模拟接口返回参数 通俗易懂,直接修改接口返回参数的值 mock作用 解决依赖问题,达到解耦作用 当我们 ...

  9. SpringBoot使用thymeleaf模板时报错:Template might not exist or might not be accessible by any of the configured Template Resolvers

    错误如下:Template might not exist or might not be accessible by any of the configured Template Resolvers ...

  10. 04-String

    动手动脑 请运行以下示例代码StringPool.java,查看其输出结果.如何解释这样的输出结果?从中你能总结出什么? s0,s1,s2字符串的内容相同,实际占用的是同一空间,引用的是同一个对象,所 ...