正解:构造

解题报告:

传送门!

交互题交互题!哇好新鲜啊QwQ

首先考虑最傻逼的做法,应该是每个人都能想到的

首先看一下它给的条件,考虑到完全二叉树的性质,就可以发现,如果给的邻居只有一个,说明是叶子,有两个,说明是根,有三个,说明是普通的节点

然后就分情况讨论鸭(以下内容都是从最差的情况即h=7为基础的讨论

如果运气好,问到了根,得嘞那就不用再问辣ans出来辣

如果问到了一个叶子节点,那就会给一个非根非叶子节点,就继续询问这个普通节点

如果问到了一个普通节点,就会有三个邻居,那就依次选,并利用已知条件优化一下

具体怎么做我就不说辣反正就是枚举一通+所有人都想得到的优化

说一下正解趴

首先可以想到,假如给一条链,链的一端是叶子节点,那么这条链上每个节点的深度都能知道了是趴

那假如我们第一次问,问到了一个普通节点,现在要求它的深度,怎么求呢

随便问两条链,从三个邻居中选出俩然后一条路问到黑的那种,经过节点数比较少的那条一定是经过它的儿子的笔直向下的一条链(如果相等就都是)(不理解的可以画下图很快就能get辣

同时我们还可以知道三个邻居中哪个是它爹哪些是它崽

然后我们就能get一个构造方法

随机一个点,按照上面的方法求出它的深度

        ↓

找到当前已知深度最低的点

↓          ↑

随机一条链,更新当前点祖先的深度,回到操作2

就这么一直做做做下去就能保证一直往上就能找到根节点了嘛

但是继续思考

当h=7的时候,假如运气有这——么背,当询问到深度=2的时候(规定根节点深度为1),如果选一条链通向叶子节点,就要问5次,就会要超过辣

但是考虑,当深度=2的时候,我们未知的邻居节点只有两个,一定有一个是根,所以只要问1次就出来了,问5次肯定亏辣

当深度=3的时候一样,具体不剖析了反正一样是,打破砂锅问到底就很亏不如直接问

最后通过一系列计算可以发现当最惨的情况下也只用问17次,但是第17次问到的一定是树根,所以其实只要问16次,就刚好!

over!

#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<string>
#include<cmath>
#include<cstdio>
#include<vector>
using namespace std;
#define ll int
#define il inline
#define rg register
#define rp(i,x,y) for(rg ll i=x;i<=y;++i)
#define chck(x) if(l[x]==2)return void(print(x)); const ll N=+;
ll h,l[N],a[N][],q[],T,head,tail;
bool used[N],gdgs=; il void get(ll x){if(used[x])return;cout<<"? "<<x<<endl;cout.flush();used[x]=;cin>>l[x];rp(i,,l[x])cin>>a[x][i];}
il void print(ll x){cout<<"! "<<x<<endl;cout.flush();}
il bool isleaf(ll x){return l[x]==;}
il void solv()
{
memset(used,,sizeof(used));cin>>h;get();head=tail=;chck();q[]=;
if(!isleaf())
{
q[++tail]=a[][];
while(gdgs)
{
get(q[tail]);if(isleaf(q[tail]))break;
rp(i,,l[q[tail]])if(a[q[tail]][i]!=q[tail-]){q[tail+]=a[q[tail]][i];++tail;break;}
}
q[--head]=a[][];
while(gdgs)
{
get(q[head]);if(isleaf(q[head]))break;
rp(i,,l[q[head]])if(a[q[head]][i]!=q[head+]){q[head-]=a[q[head]][i];--head;break;}
}
}
ll dep=h-((tail-head)>>),nw=q[(head+tail)>>];
while(gdgs)
{
if(dep<=)
{
if(dep==)return void(print(nw));
rp(i,,l[nw])if(!used[a[nw][i]]){nw=a[nw][i];break;}
--dep;
if(dep==)return void(print(nw));
if(dep==)
{
ll tmp[],len=;get(nw);
rp(i,,l[nw])if(!used[a[nw][i]])tmp[++len]=a[nw][i];
rp(i,,len-){get(tmp[i]);chck(tmp[i]);}
return void(print(tmp[len]));
}
else
{
ll tmp[],len=,tmp2[],len2=;get(nw);
rp(i,,l[nw])if(!used[a[nw][i]])tmp[++len]=a[nw][i];
rp(i,,len){get(tmp[i]);rp(j,,l[tmp[i]])if(!used[a[tmp[i]][j]])tmp2[++len2]=a[tmp[i]][j];}
rp(i,,len2-){get(tmp2[i]);chck(tmp2[i]);}
return void(print(tmp2[len2]));
}
}
head=tail=;q[tail]=nw;
while(gdgs)
{
get(q[tail]);if(isleaf(q[tail]) && tail>)break;chck(q[tail]);
rp(i,,l[q[tail]])if(!used[a[q[tail]][i]]){q[tail+]=a[q[tail]][i];++tail;break;}
}
nw=q[(tail-h+dep)>>];dep-=(tail-h+dep)>>;
}
} int main()
{
cin>>T;
while(T--)solv();
}

代码有这——么难打呜呜呜!

CF750F New Year and Finding Roots 构造+树论的更多相关文章

  1. C#结合Jquery LigerUI Tree插件构造树

    Jquery LigerUI Tree是Jquery LigerUI()的插件之一,使用它可以快速的构建树形菜单.呵呵 废话不说了,直入正题,下面介绍C#结合ligerui 构造树形菜单的两种方法 1 ...

  2. java 根据 根节点及所有子成员 构造树tree

    实体类entity package com.ompa.biz.entity; import java.util.ArrayList; import java.util.List; public cla ...

  3. C# 递归构造树状数据结构(泛型),如何构造?如何查询?

    十年河东,十年河西,莫欺少年穷. 学无止境,精益求精 难得有清闲的一上午,索性写篇博客. 首先,我们需要准备一张表,如下范例: create table TreeTable ( TreeId ) no ...

  4. 简洁常用权限系统的设计与实现(四):不维护level,用递归方式构造树

    第三篇中,我们通过维护节点的深度level,通过迭代所有的节点,只需要一次,就构造了树.  本篇,换一种方式. 好处是:不维护节点的深度level,增加和修改节点时,也不用维护.递归实现,代码比较清晰 ...

  5. 简洁常用权限系统的设计与实现(五):不维护节点的深度level,手动计算level,构造树

     这种方式,与第三篇中介绍的类似.不同的是,数据库中不存储节点的深度level,增加和修改时,也不用维护.而是,在程序中,实时去计算的. 至于后面的,按照level升序排序,再迭代所有的节点构造树,与 ...

  6. Object-Widgets-Quick 构造树

    Object Tree 当以某个QObject为父类创建一个QObject时, 它会被添加到该父类的children列表中. 析构时, QObjet 会首先检查自己的children, 依次析构, 然 ...

  7. 根据 中序遍历 和 后序遍历构造树(Presentation)(C++)

    好不容易又到周五了,周末终于可以休息休息了.写这一篇随笔只是心血来潮,下午问了一位朋友PAT考的如何,顺便看一下他考的试题,里面有最后一道题,是关于给出中序遍历和后序遍历然后求一个层次遍历.等等,我找 ...

  8. CF1003E Tree Constructing 构造+树论

    正解:构造 解题报告: 传送门! 这题麻油翻译鸭,,,那就先大概港下题意趴QAQ 构造一棵n个点,直径为d,每个点点度不超过k的树 这题其实我jio得还是比较简单的趴,,, 首先构造出一条直径,就是一 ...

  9. 树上的构造 树分治+树重心的性质 Codeforces Round #190 (Div. 2) E

    http://codeforces.com/contest/322/problem/E E. Ciel the Commander time limit per test 1 second memor ...

随机推荐

  1. 【重要】攻击动作时间段判断~使用动画time比较动画length和使用一个变量数组做延迟

    using UnityEngine; using System.Linq; using System.Collections.Generic; [RequireComponent(typeof(Cha ...

  2. React Native(十二)——嵌套WebView中的返回处理

    情景描述: 从一个名为"My"的组件点击进去,进入一个列表(该列表内容为webView中内容),其中一个webView也可以点击进入详情页(也为webView),但是如果对导航栏不 ...

  3. myeclipse使用小技巧

    1 如何关掉maven自动更新,去掉前面的勾 2 myeclipse中如何设置不校验js

  4. struts.xml文件中配置tiles.xml

    Apache Tiles是一个JavaEE应用的页面布局框架.Tiles框架提供了一种模板机制,可以为某一类页面定义一个通用的模板,该模板定义了页面的整体布局.布局由可以复用的多个块组成,每个页面可以 ...

  5. Python六大开源框架对比:Web2py略胜一筹(转)

    Python是一门动态.面向对象语言.其最初就是作为一门面向对象语言设计的,并且在后期又加入了一些更高级的特性.除了语言本身的设计目的之外,Python标准库也是值得大家称赞的,Python甚至还自带 ...

  6. 子页面iframe跨域执行父页面定义的JS方法

    问题需求:父页面与子页面iframe跨域嵌套,子页面要触发父页面所定义的js方法.父子页面的数据传递. 下文中会用到一些文件:父页面: parent.html嵌在父页面的子iframe页面:child ...

  7. NC 的高级应用

    高级用法: (1)作攻击程序用,例子: 格式1:type.exe c:\exploit.txt|nc -nvv 192.168.x.x 80 格式2:nc -nvv 192.168.x.x 80 &l ...

  8. sencha touch Ext.app.Application

    Ext.app.Application一般用于app.js中 用来初始化整个应用 可以预先加载controllers(控制器),models(模型),stores(数据源),views(视图) 例如: ...

  9. 一篇博客搞定redis基础

    redis简介 redis 一款高性能key-value数据库,实际上多用作缓存队列或者消息分发(celery),但是最常常被用来做缓存. redis安装 源码安装 $ wget http://dow ...

  10. STM8L外部中断 为何 死循环 寄存器操作

    STM8L 系列单片机是 ST公司推出的低功耗单片机,与STM8S系列相比功耗降低了很多,但内部结构也删减了很多,使用时一定要仔细阅读手册.  这是第一次使用STM8,实现功能不是很复杂就没想研究库函 ...