期末考前写题解,\(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. JS 中检测数组的四种方法

    今天和大家分享一下 JS 中检测是不是数组的四种方法,虽然篇幅不长,不过方法应该算是比较全面了. 1. instanceof 方法 instanceof 用于检测一个对象是不是某个类的实例,数组也是一 ...

  2. 小程序和wepy做循环渲染如何点击拿到相对应的值

    数据和其他的就忽略,简单上手,wepy的for渲染方式改成对应的就行,传参触发不用改 <view wx:for="{{list}}"> {{item.title}} & ...

  3. 【Spring Boot 源码解读】之 【为何引入了 Jedis 依赖最后用的还是 Lettuce 客户端?】

    1.Spring Boot 2.x 的两种 Redis 客户端 首先,我们都知道,从 Spring Boot 2.x 开始 Lettuce 已取代 Jedis 成为首选 Redis 的客户端.当然 S ...

  4. 晨叔技术晨报: 你真的搞懂JS中的“值传递”和“引用传递”吗?

    晨叔周刊,每周一话题,技术天天涨. 本周的话题是JS的内存问题(加入本周话题,请点击传送门). 图 话题入口 今天的技术晨报来,就来谈谈JS中变量的,值传递和引用传递的问题.现在,对于很多的JSer来 ...

  5. mongo repository

    using MongoDB.Driver; namespace Dben.Invoice.Repository { /// <summary> /// 仓储基类 /// </summ ...

  6. 区间dp - 不连续的回文串

    Long long ago, there lived two rabbits Tom and Jerry in the forest. On a sunny afternoon, they plann ...

  7. redis 其他操作

    1.设定服务端密码 1.1.编辑 redis的配置文件 [root@centos7 ~]# vim /usr/local/redis/etc/redis.conf requirepass 123 # ...

  8. 《爬虫学习》(二)(urllib库使用)

    urllib库是Python中一个最基本的网络请求库.可以模拟浏览器的行为,向指定的服务器发送一个请求,并可以保存服务器返回的数据. 1.urlopen函数: 在Python3的urllib库中,所有 ...

  9. ASP.NET Core下Ocelot的简单使用

    一.创建demo项目 1.新建webapi项目,命名为“DemoProject”,去掉HTTPS勾选 using Microsoft.AspNetCore.Mvc; using System.Coll ...

  10. 动态规划-Dynamic Programming(DP)

    动态规划 动态规划方法心得 ​ 动态规划是一般的面试.笔试中的高频算法题,熟练掌握必要的.动态规划的中心思想是在解决当前问题时,可以由之前已经计算所得的结果并结合现在的限制条件递推出结果.由于此前的计 ...