题目链接

https://loj.ac/problem/6669

题解

Orz yyf太神了,出这种又有意思又有意义的好题造福人类……

首先\(n\)次询问求出所有节点的深度。

考虑按深度扩展(BFS), 同时维护重链剖分

每次扩展一个点时,从根节点所在重链开始,每次询问当前节点与链底节点的距离,这样就可以算出它们LCA的深度,也就是当前节点到根的路径上与这条重链相交部分的最大深度。那么如果这个最大深度等于当前深度\(-1\), 就得到了该点的父亲;否则跳到LCA的轻儿子所在重链上,继续询问即可。

时间复杂度\(O(n^2)\), 询问次数\(O(n\log n)\).

代码

比我想象中的好写一些。

#include<bits/stdc++.h>
#define llong long long
using namespace std; inline int read()
{
int x = 0,f = 1; char ch = getchar();
for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}
return x*f;
} const int N = 3000;
int son[N+3][2];
int hvs[N+3];
int dep[N+3];
int fa[N+3];
int sz[N+3];
vector<int> idep[N+3];
int n; int getbtn(int u) {while(son[u][hvs[u]]) {u = son[u][hvs[u]];} return u;}
int jumpup(int u,int x) {while(x--) {u = fa[u];} return u;}
int jumpdown(int u,int x) {while(x--) {u = son[u][hvs[u]];} return u;}
void verify(int u) {hvs[u] = (sz[son[u][1]]>sz[son[u][0]]);}
void setfa(int u,int v) //fa[u]=v
{
// printf("setfa %d %d\n",u,v);
fa[u] = v; sz[u] = 1; son[v][son[v][0]?1:0] = u;
while(v)
{
verify(v); sz[v]++; v = fa[v];
}
} void work(int u)
{
int v = getbtn(1);
while(1)
{
printf("? %d %d\n",v,u); fflush(stdout);
int dis; scanf("%d",&dis);
int deplca = (dep[u]+dep[v]-dis)>>1;
v = jumpup(v,dep[v]-deplca);
if(dep[u]-deplca==1) {setfa(u,v); return;}
v = son[v][hvs[v]^1]; v = getbtn(v);
}
} int main()
{
scanf("%d",&n);
for(int i=2; i<=n; i++) {printf("? %d %d\n",1,i); fflush(stdout); scanf("%d",&dep[i]); idep[dep[i]].push_back(i);}
for(int i=0; i<idep[1].size(); i++) {setfa(idep[1][i],1);}
for(int i=2; i<=n; i++)
{
for(int j=0; j<idep[i].size(); j++)
{
int u = idep[i][j];
work(u);
}
}
printf("! "); for(int i=2; i<=n; i++) printf("%d ",fa[i]); puts(""); fflush(stdout);
return 0;
}

LOJ #6669 Nauuo and Binary Tree (交互题、树链剖分)的更多相关文章

  1. Water Tree CodeForces 343D 树链剖分+线段树

    Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...

  2. [POJ3237]Tree解题报告|树链剖分|边剖

    关于边剖 之前做的大多是点剖,其实转换到边剖非常简单. 我的做法是每个点的点权记录其到父亲节点的边的边权. 只要solve的时候不要把最上面的点记录在内就可以了. Tree Description Y ...

  3. Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  4. Codeforces Round #329 (Div. 2) D. Happy Tree Party LCA/树链剖分

    D. Happy Tree Party     Bogdan has a birthday today and mom gave him a tree consisting of n vertecie ...

  5. 2019 icpc南昌全国邀请赛-网络选拔赛J题 树链剖分+离线询问

    链接:https://nanti.jisuanke.com/t/38229 题意: 给一棵树,多次查询,每次查询两点之间权值<=k的边个数 题解: 离线询问,树链剖分后bit维护有贡献的位置即可 ...

  6. [luogu3676] 小清新数据结构题 [树链剖分+线段树]

    题面 传送门 思路 本来以为这道题可以LCT维护子树信息直接做的,后来发现这样会因为splay形态改变影响子树权值平方和,是splay本身的局限性导致的 所以只能另辟蹊径 首先,我们考虑询问点都在1的 ...

  7. CF504E Misha and LCP on Tree 后缀自动机+树链剖分+倍增

    求树上两条路径的 LCP (树上每个节点代表一个字符) 总共写+调了6个多小时,终于过了~ 绝对是我写过的最复杂的数据结构了 我们对这棵树进行轻重链剖分,然后把所有的重链分正串,反串插入到广义后缀自动 ...

  8. BZOJ3637 Query on a tree VI(树链剖分+线段树)

    考虑对于每一个点维护子树内与其连通的点的信息.为了换色需要,记录每个点黑白两种情况下子树内连通块的大小. 查询时,找到深度最浅的同色祖先即可,这可以比较简单的树剖+线段树乱搞一下(似乎就是qtree3 ...

  9. HYSBZ 1036 树的统计Count (水题树链剖分)

    题意:中文题. 析:就是直接维护一个最大值和一个和,用线段树维护即可,这个题很简单,但是我卡了一晚上,就是在定位的时候,位置直接反过来了,但是样例全过了...真是... 代码如下: #pragma c ...

随机推荐

  1. (三)Spring框架之事务管理

    一.编程式事务管理 Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager,事务管理器接口PlatformT ...

  2. (四)输入参数与输出类型为复杂类型的web服务

    一. 服务端发布服务 1.1 定义复杂类型:UserBean.java package service; public class UserBean { private String userId; ...

  3. zookeeper安装和使用 windows环境

    简介 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提 ...

  4. Xamarin开发综述

    https://blog.csdn.net/qq_41647999/article/details/84844357 一. 前言这十来天对Xamarin的学习踩了很多的坑,说来也是一把心酸泪,下面为大 ...

  5. Linux Centos7配置mysql8.0数据库

    本文转至:672530440 在此感谢博主,撒花!!! 本文主要从以下几个方面对自己在centos7 下安装mysql8过程做如下总结: CentOS7 安装mysql8 步骤: window下的Na ...

  6. form-create教程:移除默认提交按钮

    本文将介绍form-create如何修改,隐藏默认提交按钮 form-create 是一个可以通过 JSON 生成具有动态渲染.数据收集.验证和提交功能的表单生成器.并且支持生成任何 Vue 组件.结 ...

  7. php文件包含漏洞 file inclusion vulnerability

    0x00 何为文件包含漏洞 开发人员如果在写类似include "a.php"的代码时,如果将a.php写成了可变的值,那么就可以在上面做文章,举个理想的例子: <? inc ...

  8. B+树Java代码实现以及测试

    M阶B+树的定义: 任意非叶子结点最多有M个子节点:且M>2: 除根结点以外的非叶子结点至少有 M/2个子节点: 根结点至少有2个子节点: 除根节点外每个结点存放至少M/2和至多M个关键字:(至 ...

  9. 将用户赋予sudo权限:配置sudoers文件

    xxx is not in the sudoers file.This incident will be reported.的解决方法   1.切换到root用户下,怎么切换就不用说了吧,不会的自己百 ...

  10. sql注入原理,利用与防护

    一.sql注入原理 注入攻击的本质就是把用户输入的数据当作代码来执行.所以注入攻击有两个必要条件 1.用户能够控制的输入. 2.原本程序要执行的代码,拼接了用户输入的数据. 二.sql注入分类 按照请 ...