题面

一棵以

1

1

1 为根的

N

N

N 个节点的有根树,

Q

Q

Q 次询问,每次问一个点

u

u

u 的

k

k

k 级兄弟有多少个(第

k

k

k 代祖先的第

k

k

k 代孩子),如果没有则输出 0

N

,

Q

1

0

6

N,Q\leq 10^6

N,Q≤106 。

题解

像这种一个 log 可过的题目就是拿来 O(n) 做的

狗狗有言:挺板的长链剖分。

我们用离线+长链剖分来解决第

k

k

k 代孩子的问题,每个链顶存一个数组,表示每一代孩子的个数,把轻儿子的链合并。这个是长链剖分的常有操作,总共复杂度

O

(

n

)

O(n)

O(n) 。

如何

O

(

1

)

O(1)

O(1) 找

k

k

k 级祖先,这个很简单,不必用倍增。只需要把询问挂到树上,然后

d

f

s

\rm dfs

dfs 临时用一个数组栈存祖先就行了。

CODE

唉,又水了一篇

全程不用 vector ,常数极小

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<ctime>
#include<queue>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 1000005
#define LL long long
#define DB double
#define ENDL putchar('\n')
#define lowbit(x) (-(x) & (x))
#define FI first
#define SE second
#define eps (1e-4)
LL read() {
LL f=1,x=0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f*x;
}
void putpos(LL x) {
if(!x) return ;
putpos(x/10); putchar('0'+(x%10));
}
void putnum(LL x) {
if(!x) putchar('0');
else if(x < 0) putchar('-'),putpos(-x);
else putpos(x);
}
const int MOD = 1000000007;
int n,m,s,o,k;
int hd[MAXN],v[MAXN],nx[MAXN],cnt;
void ins(int x,int y) {
v[++ cnt] = y; nx[cnt] = hd[x];
hd[x] = cnt; return ;
}
int d[MAXN],le[MAXN],son[MAXN]; int hd2[MAXN],nx2[MAXN];
int U[MAXN],kk[MAXN],fa[MAXN],as[MAXN];
int st[MAXN],tp;
int ar[MAXN<<1],he[MAXN],CN;
void dfs0(int x,int ff) {
d[x] = d[ff] + 1;
st[++ tp] = x;
for(int i = hd2[x];i;i = nx2[i]) {
if(kk[i] >= d[x]) fa[i] = 0;
else fa[i] = st[tp-kk[i]];
}
hd2[x] = 0;
for(int i = hd[x];i;i = nx[i]) {
dfs0(v[i],x);
le[x] = max(le[x],le[v[i]] + 1);
if(le[v[i]] >= le[son[x]]) son[x] = v[i];
}
tp --;
return ;
}
void dfs(int x,int ff) {
he[x] = ++ CN;
ar[he[x]] ++;
if(son[x]) dfs(son[x],x);
for(int i = hd[x];i;i = nx[i]) {
if(v[i] != son[x]) {
dfs(v[i],x);
for(int j = 0;j <= le[v[i]];j ++) {
ar[he[x]+j+1] += ar[he[v[i]]+j];
}
}
}
for(int i = hd2[x];i;i = nx2[i]) {
int le = d[U[i]] - d[x];
as[i] = ar[he[x]+le] - 1;
}
return ;
}
int main() {
n = read();m = read();
for(int i = 2;i <= n;i ++) {
s = read();o = i;
ins(s,o);
}
for(int i = 1;i <= m;i ++) {
U[i] = s = read();kk[i] = read();
nx2[i] = hd2[s]; hd2[s] = i;
}
dfs0(1,0);
for(int i = 1;i <= m;i ++) {
if(!fa[i]) continue;
nx2[i] = hd2[fa[i]]; hd2[fa[i]] = i;
}
dfs(1,0);
for(int i = 1;i <= m;i ++) {
putnum(as[i]);
if(i < m) putchar(' ');
}ENDL;
return 0;
}

P5384[Cnoi2019]雪松果树 (长链剖分)的更多相关文章

  1. [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分

    题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...

  2. LOJ3053 十二省联考2019 希望 容斥、树形DP、长链剖分

    传送门 官方题解其实讲的挺清楚了,就是锅有点多-- 一些有启发性的部分分 L=N 一个经典(反正我是不会)的容斥:最后的答案=对于每个点能够以它作为集合点的方案数-对于每条边能够以其两个端点作为集合点 ...

  3. BZOJ 3653: 谈笑风生(离线, 长链剖分, 后缀和)

    题意 给你一颗有 \(n\) 个点并且以 \(1\) 为根的树.共有 \(q\) 次询问,每次询问两个参数 \(p, k\) .询问有多少对点 \((p, a, b)\) 满足 \(p,a,b\) 为 ...

  4. 2019.03.11 COGS2652 秘术(天文密葬法)(分数规划+长链剖分)

    传送门 题意:nnn个点的树,每个点两个值a,ba,ba,b,问长度为mmm的路径∑ai∑bi\frac{\sum a_i}{\sum b_i}∑bi​∑ai​​的最大值. 思路:一眼要01分数规划, ...

  5. 【BZOJ3522】【BZOJ4543】【POI2014】Hotel 树形DP 长链剖分 启发式合并

    题目大意 ​ 给你一棵树,求有多少个组点满足\(x\neq y,x\neq z,y\neq z,dist_{x,y}=dist_{x,z}=dist_{y,z}\) ​ \(1\leq n\leq 1 ...

  6. 【Vijos】lxhgww的奇思妙想(长链剖分)

    题面 给定一棵树,每次询问一个点的\(k\)次祖先,强制在线. Vijos 题解 长链剖分. 链接暂时咕咕咕了. 现在可以戳链接看题解了 #include<iostream> #inclu ...

  7. 【BZOJ4543】Hotel加强版(长链剖分)

    [BZOJ4543]Hotel加强版(长链剖分) 题面 BZOJ,没有题面 洛谷,只是普通版本 题解 原来我们的\(O(n^2)\)做法是设\(f[i][j]\)表示以\(i\)为根的子树中,距离\( ...

  8. 【BZOJ3653】谈笑风生(长链剖分)

    [BZOJ3653]谈笑风生(长链剖分) 题面 BZOJ 洛谷 权限题啊.... 题解 首先根据题目给的条件,发现\(a,b\)都要是\(c\)的父亲. 所以这三个点是树上的一条深度单增的链. 因为\ ...

  9. 【CF1009F】Dominant Indices(长链剖分)

    [CF1009F]Dominant Indices(长链剖分) 题面 洛谷 CF 翻译: 给定一棵\(n\)个点,以\(1\)号点为根的有根树. 对于每个点,回答在它子树中, 假设距离它为\(d\)的 ...

随机推荐

  1. torch.cat()和torch.stack()

    torch.cat() 和 torch.stack()略有不同torch.cat(tensors,dim=0,out=None)→ Tensortorch.cat()对tensors沿指定维度拼接,但 ...

  2. 【二分图】匈牙利 & KM

    [二分图]匈牙利 & KM 二分图 概念: 一个图 \(G=(V,E)\) 是无向图,如果顶点 \(V\) 可以分成两个互不相交地子集 \(X,Y\) 且任意一条边的两个顶点一个在 \(X\) ...

  3. 2021.05.04【NOIP提高B组】模拟 总结

    T1 题目大意, \(S_{i,j}=\sum_{k=i}^j a_k\) ,求 \(ans=\min\{ S_{i,j}\mod P|S_{i,j}\mod P\ge K \}\) 其中 \(i\l ...

  4. 第6章 字符串(上)——C风格字符串

    6.1 C-strings(C 风格字符串) C风格字符串: 字符数组是元素为字符型的数组,字符串是以空字符'\0' 作为数组最后一个元素的字符数组. 如果指定了数组的大小,而字符串的长度又小于数组大 ...

  5. Linux免密登陆配置(互信配置)

    Linux免密登陆配置(互信配置) 1.生成当前用户的秘钥文件 [oracle@localhost .ssh]$ ssh-keygen -t rsa 2.配置远程登录用户的公钥文件 将公钥文件拷贝至另 ...

  6. 多路分支、for循环

    多路分支 多路分支也叫做switch语句,它的格式: switch (控制表达式){ case 条件: 输出....} switch 可以看成一种跳转,每当我们满足跳转就会跳转到响应的位置,接下我们写 ...

  7. ExtJS 布局-Center布局(Center layout)

    更新记录: 2022年6月12日 检查发布. 2022年6月1日 开始. 1.说明 center布局将子项放置在容器的中心. 2.设置布局方法 在父容器中设置 layout: 'center', // ...

  8. SpringBoot的浅浅配置和小整合

    SpringBoot的浅浅配置和小整合 本文如题,就是浅浅记录一下学习的过程中一些过程,比较简单,并没有多少深度.谢谢! SpringBoot创建 从IDEA中新建项目或者模块.注意jdk版本,一般不 ...

  9. 详细图解 Netty Reactor 启动全流程 | 万字长文 | 多图预警

    本系列Netty源码解析文章基于 4.1.56.Final版本 大家第一眼看到这幅流程图,是不是脑瓜子嗡嗡的呢? 大家先不要惊慌,问题不大,本文笔者的目的就是要让大家清晰的理解这幅流程图,从而深刻的理 ...

  10. 《AlignedReID:Surpassing Human-Level Performance in Person Re-Identification》理解