P5384[Cnoi2019]雪松果树 (长链剖分)
题面
一棵以
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]雪松果树 (长链剖分)的更多相关文章
- [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分
题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...
- LOJ3053 十二省联考2019 希望 容斥、树形DP、长链剖分
传送门 官方题解其实讲的挺清楚了,就是锅有点多-- 一些有启发性的部分分 L=N 一个经典(反正我是不会)的容斥:最后的答案=对于每个点能够以它作为集合点的方案数-对于每条边能够以其两个端点作为集合点 ...
- BZOJ 3653: 谈笑风生(离线, 长链剖分, 后缀和)
题意 给你一颗有 \(n\) 个点并且以 \(1\) 为根的树.共有 \(q\) 次询问,每次询问两个参数 \(p, k\) .询问有多少对点 \((p, a, b)\) 满足 \(p,a,b\) 为 ...
- 2019.03.11 COGS2652 秘术(天文密葬法)(分数规划+长链剖分)
传送门 题意:nnn个点的树,每个点两个值a,ba,ba,b,问长度为mmm的路径∑ai∑bi\frac{\sum a_i}{\sum b_i}∑bi∑ai的最大值. 思路:一眼要01分数规划, ...
- 【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 ...
- 【Vijos】lxhgww的奇思妙想(长链剖分)
题面 给定一棵树,每次询问一个点的\(k\)次祖先,强制在线. Vijos 题解 长链剖分. 链接暂时咕咕咕了. 现在可以戳链接看题解了 #include<iostream> #inclu ...
- 【BZOJ4543】Hotel加强版(长链剖分)
[BZOJ4543]Hotel加强版(长链剖分) 题面 BZOJ,没有题面 洛谷,只是普通版本 题解 原来我们的\(O(n^2)\)做法是设\(f[i][j]\)表示以\(i\)为根的子树中,距离\( ...
- 【BZOJ3653】谈笑风生(长链剖分)
[BZOJ3653]谈笑风生(长链剖分) 题面 BZOJ 洛谷 权限题啊.... 题解 首先根据题目给的条件,发现\(a,b\)都要是\(c\)的父亲. 所以这三个点是树上的一条深度单增的链. 因为\ ...
- 【CF1009F】Dominant Indices(长链剖分)
[CF1009F]Dominant Indices(长链剖分) 题面 洛谷 CF 翻译: 给定一棵\(n\)个点,以\(1\)号点为根的有根树. 对于每个点,回答在它子树中, 假设距离它为\(d\)的 ...
随机推荐
- 洛谷 P2629 好消息,坏消息 题解
暴力算法的时间复杂度是O(n^2),考虑优化: 先导入一种思想--断环为链.说通俗点就是在原数组后面再接上下标为1--(n - 1)的元素: 以样例为例:-3 5 1 2:我们将其断环为链后可以得到这 ...
- 商户编号[Merchant Id]是什么
1. Merchant Id是什么 2. Merchant Id 是有哪几个部分构成的 2.1 收单机构代码 2.2 商户地区代码 2.3 Merchant Category Code(MCC) 本文 ...
- 动态线程池框架 DynamicTp v1.0.6版本发布。还在为Dubbo线程池耗尽烦恼吗?还在为Mq消费积压烦恼吗?
DynamicTp 简介 DynamicTp 是一个基于配置中心实现的轻量级动态线程池管理工具,主要功能可以总结为 动态调参.通知报警.运行监控.三方包线程池管理等几大类. 经过几个版本迭代,目前最新 ...
- Banner自定义图案
Banner大全https://www.bootschool.net/ascii
- pytest多进程/多线程执行测试用例
前言: 实际项目中的用例数量会非常多,几百上千:如果采用单进程串行执行的话会非常耗费时间.假设每条用例耗时2s,1000条就需要2000s $\approx$ 33min:还要加上用例加载.测试前/后 ...
- Http实战之Wireshark抓包分析
Http实战之Wireshark抓包分析 Http相关的文章网上一搜一大把,所以笔者这一系列的文章不会只陈述一些概念,更多的是通过实战(抓包+代码实现)的方式来跟大家讨论Http协议中的各种细节,帮助 ...
- Transferable Joint Attribute-Identity Deep Learning for Unsupervised Person Re-Identification理解
简介:这篇文章属于跨域无监督行人再识别,不同于大部分文章它使用了属性标注.旨在于能够学习到有属性语义与有区分力的身份特征的表达空间(TJ-AIDL),并能够转移到一个没有看到过的域. 贡献: 提出了一 ...
- JDBCTools 第一个版本
JDBCToolV1: package com.dgd.test; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax ...
- C# 11 的新特性和改进前瞻
前言 .NET 7 的开发还剩下一个多月就要进入 RC,C# 11 的新特性和改进也即将敲定.在这个时间点上,不少新特性都已经实现完毕并合并入主分支 C# 11 包含的新特性和改进非常多,类型系统相比 ...
- C#实现FFT(递归法)
C#实现FFT(递归法) 1. C#实现复数类 我们在进行信号分析的时候,难免会使用到复数.但是遗憾的是,C#没有自带的复数类,以下提供了一种复数类的构建方法. 复数相比于实数,可以理解为一个二维数, ...