#轻重链剖分,交互#LOJ 6669 Nauuo and Binary Tree
题目
有一棵大小为\(n\)只知道根节点为1的二叉树,
可以不超过\(3*10^4\)询问两点之间距离,
最后输出除了点1以外其余点的祖先
\(n\leq 3000\)
分析
\(O(n^2)\)的时间复杂度就可以了,主要是控制询问次数
首先将所有点的深度求出来,
那么询问按照点的深度递增去找该点的祖先,
有一个很重要的性质就是

通过询问可以将\(dep[x]+dep[y]-2*dep[LCA]\)求出来,由于\(dep[x]+dep[y]\)是确定的,那么\(LCA\)也可以求出来
由于\(dep[x],dep[y]\geq dep[LCA]\)所以只要按照深度一层一层找就可以询问\(x,y\)得到它们的\(LCA\)
若当前想要找的是\(x\)的祖先,那么只要找到一个合适的\(y\)让\(dep[x]=dep[LCA]+1\)即可以让\(LCA\)变成\(x\)的祖先,
那么一定让重新找\(y\)的次数最少,考虑树上的每条路径都可以被拆分成不超过\(O(\log n)\)条重链。
从根节点开始每次找重链然后如果LCA所对应的轻儿子存在那就跳到轻儿子,则总询问次数为\(O(n+n\log n)\)实际更小
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=3011;
int siz[N],son[N][2],foot[N],n,rk[N],dep[N],fat[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
bool cmp(int x,int y){return dep[x]<dep[y];}
inline signed Ask(int x,int y){
putchar(63),putchar(32),print(x),putchar(32),
print(y),putchar(10),fflush(stdout);
return iut();
}
inline void dfs1(int x){
siz[x]=1,foot[x]=x;
if (son[x][0]) dfs1(son[x][0]),siz[x]+=siz[son[x][0]];
if (son[x][1]) dfs1(son[x][1]),siz[x]+=siz[son[x][1]];
if (siz[son[x][0]]<siz[son[x][1]]) swap(son[x][0],son[x][1]);
if (son[x][0]) foot[x]=foot[son[x][0]];
}
inline void dfs2(int x,int y){
rr int now=foot[x],d=Ask(now,y);
while (dep[now]>(dep[foot[x]]+dep[y]-d)/2) now=fat[now];
if (son[now][1]) dfs2(son[now][1],y);
else{
fat[y]=now;
if (son[now][0]) son[now][1]=y;
else son[now][0]=y;
}
}
signed main(){
n=iut();
for (rr int i=2;i<=n;++i) dep[i]=Ask(1,i),rk[i]=i;
sort(rk+2,rk+1+n,cmp),fat[rk[2]]=1,son[1][0]=rk[2];
for (rr int i=3;i<=n;++i) dfs1(1),dfs2(1,rk[i]);
putchar(33);
for (rr int i=2;i<=n;++i) putchar(32),print(fat[i]);
putchar(10),fflush(stdout);
return 0;
}
#轻重链剖分,交互#LOJ 6669 Nauuo and Binary Tree的更多相关文章
- LOJ #6669 Nauuo and Binary Tree (交互题、树链剖分)
题目链接 https://loj.ac/problem/6669 题解 Orz yyf太神了,出这种又有意思又有意义的好题造福人类-- 首先\(n\)次询问求出所有节点的深度. 考虑按深度扩展(BFS ...
- 树链剖分 (求LCA,第K祖先,轻重链剖分、长链剖分)
2020/4/30 15:55 树链剖分是一种十分实用的树的方法,用来处理LCA等祖先问题,以及对一棵树上的节点进行批量修改.权值和查询等有奇效. So, what is 树链剖分? 可以简单 ...
- 洛谷 - P2146 - 软件包管理器 - 重链剖分
https://www.luogu.org/problem/P2146 继续重链剖分. 这里好像很好懂,每次安装软件就区间改值赋值整个路径是1,然后比较前后的sum值变化就可以了.事实上后一次的sum ...
- luogu P3384 【模板】重链剖分
参考https://www.cnblogs.com/wushengyang/p/10808505.html,感谢 #include<iostream> #include<algori ...
- codeforces gym 101611C 重链剖分构造
给一棵树 要求在一个20*1e6的矩阵上放下这棵树,每个点的坐标都是整数且所有边都不相叉 题解 按照重链遍历,先给轻儿子坐标,然后沿着重儿子向下走即可 #include <bits/stdc++ ...
- 【hihocoder1167】高等理论计算机科学 (重链剖分 +树状数组)
Descroption 原题链接给你一棵\(~n~\)个点的树和\(~m~\)条链,求两两相交的链有多少对,两条链相交当且仅当有至少一个公共点.\(~1 \leq n, m \leq 10 ^ 5~\ ...
- 洛谷 - P4114 - Qtree1 - 重链剖分
https://www.luogu.org/problem/P4114 维护边权的话,用深度大的点表示这条边(可以遍历一边边询问两端深度,这样不需要修改dfs1,也可以在dfs1的时候向下走的同时把边 ...
- SCUT - 297 - 狂符「幻视调律(Visionary Tuning)」 - 重链剖分
https://scut.online/p/297 一般的树剖是关于点权的,但是突发奇想好像边权也是一样的.做一些小改动. #include<bits/stdc++.h> #define ...
- 树链剖分【p4114】Qtree-Query on a tree I
Description 给定一棵n个节点的树,有两个操作: CHANGE i ti 把第i条边的边权变成ti QUERY a b 输出从a到b的路径中最大的边权,当a=b的时候,输出0 Input 第 ...
- Query on a tree——树链剖分整理
树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...
随机推荐
- 解析Spring中的循环依赖问题:再探三级缓存(AOP)
前言 在之前的内容中,我们简要探讨了循环依赖,并指出仅通过引入二级缓存即可解决此问题.然而,你可能会好奇为何在Spring框架中还需要引入三级缓存singletonFactories.在前述总结中,我 ...
- DataGear 制作自定义柱状图条目颜色的数据可视化看板
DataGear 看板提供了dg-chart-options图表选项配置功能,可自定义样式.位置.显示内容等图表选项,其中的processUpdateOptions回调函数配置项,可以在图表更新数据前 ...
- cw attack
- Java-- Arrays操纵数组的工具类
1 //操作数组的工具类 java.util.Arrays :操作数组的工具类 里面定义了很多操作数组的方法 2 public static void main(String[] args) 3 { ...
- 我和我的DBA之路
这几天,突然想写写这些年的工作总结,毕业至今快20年的回顾. 想到20年前,在做毕业设计的时候,当时是学的机械工程类专业,因为带毕业设计的老师兼职企业有个门户网站的需求,而我又会做点网站设计,带的老师 ...
- PaddleOCR 服务化部署(基于PaddleHub Serving)
最近用到百度飞桨的 PaddleOCR,研究了一下PaddleOCR的服务化部署,简单记录一些部署过程和碰到的问题. 基础环境 paddlepaddle 2.5.2 python 3.7 paddle ...
- 基于 XAF Blazor 的规则引擎编辑器
开源项目地址:https://gitee.com/lowcodexaf/rules-engine-editor 前言 本项目是基于XAFBlazor的规则引擎编辑器,规则引擎采用的是微软开源的Rule ...
- 用python生成正玄波信号源码解析
一 前记 项目需要生成不同频点的正玄波信号,没找到现成的软件,只能自己写一个了.顺便温习一下python. 二 源码解析: #!/usr/bin/python import numpy as np f ...
- C语言中的强制转换
许久没有遇到的问题 C语言真是博大精深,越使用它,就越发感觉到它的威力和恐怖,最近在做算法的时候,遇到了一个强转的错误,把人折腾的够受,这次要好好梳理一下了,希望下次不能再犯此类的问题. 强制转换 ...
- JSF之常用注解
@ManagedBean 以托管 bean 的形式注册一个类实例,然后将其放入到使用其中一个 @...Scoped 注释指定的范围内.如果没有指定任何范围,JSF 将把此 bean 放入请求范围,如果 ...