luoguP3066 [USACO12DEC]逃跑的BarnRunning】的更多相关文章

luoguP3066 [USACO12DEC]逃跑的BarnRunning 题目大意 给定一棵n个节点的树和参数L,查询每个节点子树中到达该节点距离<=L的数量(包括该节点) 偏模板的主席树 PS:注意一下输入格式 dfs:得出每个子树时间戳区间,每个节点到根节点的距离,仔细理解一下几个数组的含义吧,dalao直接略过 update:这题以时间戳(i)为关键字继承(i-1) query:直接查询每个子树的时间戳区间里<=dep[i]+L 这里用到了一个小技巧,就是为了避免特判,b数组加一个虚节…
[USACO12DEC]逃跑的BarnRunning Away From- 题目描述 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 nu…
目录 题目 思路 错误&&注意 代码 题目 luoguP3066 思路 虽说这个题目有多种做法,但 左偏树算法: 我们发现这个合并的时候并不好合并,因为存的值不是固定的 那我们是不是可以lazy数组呢 因为是两个颗树合并,显然是步阔以的 那就转换一下思路,什么是固定的呢 那就是1到i的路径 我们可以dfs出val[i]表示1到i的路径和 这个val也就是左偏树的初始值 然后我们发现,一个树i的所有后代x 都要经过1到i的所经过的路径 所以直接维护val,只需要在比较的时候减去val[i]即…
题面 题目描述 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个. 输入格式: 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 pa…
题面链接 一句话题意:给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个. 我:似乎并不好做啊...看了题解后大雾... sol:考虑树上差分,对于一个点,在他那个位置++,再找到最远的一个点使得该点与当前点的距离小于等于l,在找到的那个点的父亲处--,至于实现倍增好像可以轻松解决. #include <cstdio> using namespace std; #define int long long ; ],re[N],d[N]; signed main() {…
题意 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个 题解 似乎有好多种做法啊……然而蒟蒻只会打打主席树的板子…… 调了一个上午一直WA……狠下心来重打一遍居然直接一遍过…… 先dfs一遍,把到根节点的距离算出来,然后建出树上的主席树 然后考虑,$d[v]-d[u]<=L$,$d[v]<=L+d[u]$ 然后就是对于每一个$d[u]+L$查询一下区间内有多少比它小的就好 细节问题:因为不能保证$d[u]+L$在离散化后的数组内存在,所以要用upper_bound,…
好像是某CF的题,不记得…… 很套路的题,但是觉得可以做一下笔记. 倍增 + 差分. 有一个比较简单的思路就是每一个点$x$向上走一走,直到走到一个点$y$使总路程恰好不超过超过了$L$,然后把$(x, y)$这条链上的答案$ + 1$. 可以用倍增优化走一走的过程,可以用差分实现把一条向上的树链$+ 1$的操作. 时间复杂度$O(nlogn)$. Code: #include <cstdio> #include <cstring> using namespace std; typ…
题意 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个. 树上二分.这个做法还是基于树上差分的,也就是对于每一个点uu,我们要找到它向上跳LL的长度最高能够跳到的祖先.(当然倍增求出这个连dfsdfs都不用更加粗暴.)因此我们不仅要记录每一个节点到根节点的距离disdis,还要记录每一个节点到根节点要经过边的边数,也即点的深度depdep.然后再用tmptmp数组记录从根节点到uu经过的每一个点,tmp[i]tmp[i]表示从根节点到uu的路径上深度为ii的节点的编号…
code: #include <cstdio> using namespace std; #define ll long long const int N=200005; int n,fa[N][23],re[N]; ll d[N],up; int main() { //freopen("input.in","r",stdin); int i,j,tmp; scanf("%d%lld",&n,&up); re[1]=1…
LuoguP3066 先吐槽一下,这道题名字好长啊 一个非常明显的思路,利用倍增数组不断向上跳.直到数值大于\(L\),然后直接差分统计答案就好了. 这种ZROI也考过,不多赘述了. 我们来考虑主席树做法 我们设\(d_x\)为\(x\)点到跟的距离 让我们求满足\(d_v - d_u<= L,v\in Son_u\)的\(v\)的数量 转化一下式子就变成了 \(d_v <= d_u + L\) 即统计子树内有多少小于等于\(d_u+L\)的数 我们利用dfs序 将每个子树转化为一个区间 然后…