CF2032D 题解

news/2024/11/5 19:24:49/文章来源:https://www.cnblogs.com/Hanggoash/p/18528628

CF2032D 题解

题意

有一张特殊结构的树图。

通过交互来确定每个节点的父节点,即这棵树的结构。

具体还是直接上CF看吧,在题解里面太详尽地描述有点浪费时间了。

分析

可以发现 \(1\) 这个节点是比较特殊的一个节点,并且题目保证 \(1\) 一定有一个儿子。

可以从 \(1\) 入手,发现可以通过先确定 \(1\) 这条链上面的所有节点,然后从小到大枚举所有这条链之外的节点,通过询问他们是否与最小的不在链上的,且已经确定了父节点的点之间的路径,可以确定当前的节点是否是询问的节点的儿子,如果不是,那么之后一一定不会再有节点是被询问节点的儿子了,这一点可以通过反证法证明。

但是发现这种写法好像实在无法满足 \(2n-6\) 次询问的严苛限制,因为确定 \(1\) 所在的链就要花上 \(n-2\) 的代价。

于是瞟了一眼题解。。。

但是只看了 Hint ,就突然醒悟了。

可以发现第一层节点的编号一定是连续且递增的,这个结论同样也可以通过反证法证明。

那么我们可以用很少的代价先确定第一层所有的节点。

之后直接从小到大询问,发现如果询问失败,那么这个节点实际上可以直接丢掉了。。。

Solution 1

那么就可以用一个 set 来维护询问的过程,没用的节点就直接删掉就可以了。

还有一个优化,就是当 set 里面只有一个节点的时候,这个唯一的节点一定是当前所需要确定的节点的父亲。

否则它的父亲只能是 \(0\) ,但这显然是和我们推出来的关于第一层的结论是矛盾的。

这是我差不多自己想出来的玄学做法。

Solution 2

其实还会发现一个性质,就是当前需要确定的节点一旦确定下来,那么它也一定是被插到了 set 的最尾部,所以大可不必用 set 来维护,

在序列上跑一个双指针就可以了。

即:\(L\) 代表现在所询问到的节点,\(R\) 代表现在需要确定的节点。

这个是std的做法,好聪明。

Code

1

#include<bits/stdc++.h>
#define int long long
using namespace std;
int res;
inline int ask(int x,int y)
{cout<<"? "<<x<<' '<<y<<endl;fflush(stdout);cin>>res;return res;
}
int n,T; 
signed main()
{cin>>T;while(T--){cin>>n;int res;vector<int> fa(n+1,0); set<int> node,del;int now=2;for(;now<=n-1;++now){if(!ask(1,now))break;node.insert(now),fa[now]=0;}fa[now]=1,node.insert(now);now++; for(;now<=n-1;++now){for(auto x:node){if(node.size()==1){fa[now]=x;del.insert(x);node.insert(now);break;}else{int ans=ask(now,x);if(ans==0){fa[now]=x;del.insert(x);node.insert(now);break;}elsedel.insert(x); }}for(auto tmp:del)node.erase(tmp);del.clear();}cout<<"!";for(int i=1;i<=n-1;++i)cout<<" "<<fa[i];cout<<endl;}return 0;
}

2

#include<bits/stdc++.h>
using namespace std;
int T,n;
int main()
{cin>>T;auto query=[&](int x,int y){int ans;cout<<"? "<<x<<' '<<y<<endl; cin>>ans;return ans;};while(T--){cin>>n;vector<int> fa(n+1,0);int l=1,r=2;while(query(l,r)) r++;fa[r]=l,l++,r++;while(r<=n-1){while(query(l,r))l++;fa[r]=l,l++,r++;}cout<<"!";for(int i=1;i<n;++i)cout<<' '<<fa[i];cout<<endl;}return 0;
}

Tip

有一个值得注意的小地方是,交互题直接用endl可以在换行的同时起到刷新缓冲区的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/827273.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多校A层冲刺NOIP2024模拟赛18

赛时电脑死了,恼了就没交。赛后交是155pts。 T1 是二分答案+三维前缀和check,T2 瞎写了个搜索。 T1 选彩笔(rgb) 将r,g,b看做三个维度。 答案显然有可二分性,直接二分答案。那么就转化为是否存在一个边长为\(mid\)三维正方体,其内部有大于\(k\)个点。 三维前缀和维护即刻…

# 20222309 2024-2025-1 《网络与系统攻防技术》实验四实验报告

1.实验内容 一、恶意代码文件类型标识、脱壳与字符串提取 对提供的rada恶意代码样本,进行文件类型识别,脱壳与字符串提取,以获得rada恶意代码的编写作者,具体操作如下: (1)使用文件格式和类型识别工具,给出rada恶意代码样本的文件格式、运行平台和加壳工具; (2)使用…

从0开始搭建自己的直播平台

本文讲述了如何从0开始,利用腾讯云的平台,快速搭建一个直播平台的过程。本文讲述了如何从0开始,利用腾讯云的平台,快速搭建一个直播平台的过程。 准备工作 要有两个已经备案完成的域名。 域名申请及备案的操作,这部分可以直接看腾讯云的文档,也可以等我后面有时间自己再写…

[Zer0pts2020]easy strcmp

[Zer0pts2020]easy strcmp die查壳找到加密函数如何找到加密函数的找到init函数,跟进funcs_889 、跟进使用x交叉引用qword_201090即可找到主加密函数 那这个加密函数是如何连上main函数的呢? mainmain函数这里运用了strcmp,但我们却找不到strcmp到底对比了什么 但根据我们刚…

LDAP--Jenkins详解笔记

一、Ldap的结构1.组织角色 所有用户都可以登录,但是只有创建时的admin组角色有增删改的权限,相当于是根目录,千万不能删,删了就全没了注意,admin用户是首个超级登录用户(相当于根),需要用配置文件生成,详见:https://www.cnblogs.com/wangyuanguang/p/18189832 ##注意…

系统集成项目管理工程师笔记4 - 第四章 信息系统架构

信息系统集成项目涉及的架构通常有系统架构、数据架构、技术架构、应用架构、网络架构、安全架构; 4.1 架构基础架构的本质是决策; 4.1.1 指导思想通过指导思想的贯彻实施,推动项目多元参与者能保持集成关键价值的一致性理解,从而减少不必要的矛盾与冲突;4.1.2 设计原则太…

举例说明什么情况下会更倾向于使用抽象类而不是接口

接口和抽象类都遵循”面向接口而不是实现编码”设计原则,它可以增加代码的灵活性,可以适应不断变化的需求。 接口 vs 抽象类 继承限制:Java 中,一个类只能继承一个类,但可以实现多个接口。 继承一个类意味着失去了继承其他类的机会。行为表示:接口通常用于表示附加的行为…

智慧测绘数字化管理平台建设方案

随着信息技术的飞速发展,测绘地理信息与遥感专业正经历着一场革命性的变革。智慧测绘数字化管理平台的建设,不仅能够提高测绘数据的准确性和实时性,还能为城市规划、环境保护、灾害预防等领域提供强有力的数据支持。本文将探讨智慧测绘数字化管理平台的建设方案,以期为相关…

劫持微信聊天记录并分析还原 —— 解密数据库(二)

程序以 Python 语言开发,可读取、解密、还原微信数据库并帮助用户查看聊天记录,还可以将其聊天记录导出为csv、html等格式用于AI训练,自动回复或备份等等作用。本工具设计的初衷是用来获取微信账号的相关信息并解析PC版微信的数据库。程序以 Python 语言开发,可读取、解密、…

2024newstarweb题解

w1 headach3会赢吗 源码flag碎片X1: ZmxhZ3tXQTB3 再次查看源码flag碎片X2: IV95NF9yM2Fs 第三个页面也是直接查看源码直接改源码flag碎片X3: MXlfR3I0c1B 下一个页面直接禁用jsflag碎片X4: fSkpKcyF9 ZmxhZ3tXQTB3IV95NF9yM2FsMXlfR3I0c1BfSkpKcyF9 base64解码即可的flag智械危…

判断一个数是不是质数(素数)

​public static boolean isPrime(int n){if (n <= 3) { return n > 1;) for(int i = 2; i < n; i++){if (n % i == 0) { return false;} ) return true;} 质数(也称为素数)是指在大于1的自然数中,除了1和它本身以外不再有其他因数的数。换句话说,质数只能被1和它…