UNR 6. D2T2 神隐
\(\mathbf{Part. -1}\)
这是一道交互题。
hehe 蚤决定花费几天时间,游览下山市的最著名的旅游景点 —— 吓山。
吓山,以高低纵横,崔巍秀丽,错综复杂的地形闻名。据说无论用什么地图导航,都不能保障你在山中不迷路。
之所以会出现这样的情况,是因为吓山中的路,在没有光的时候都会发生 “神隐”。在“神隐”状态下,人们无法察觉到这条路的存在,很容易就迷路了。
吓山的地图可以简化为一个 \(n\) 个节点,编号为 \(0 \sim n-1\) 的树。它有 \(n - 1\) 条边,其中第 \(i\) 条边为 \((u_i, v_i)\)(\(0 \leq i \lt n - 1\))。每条路上都装有路灯。
为了攻略吓山,hehe 蚤和它的小伙伴们试图绘制吓山的地图。
- hehe 蚤事先从吓山管理员那里拿到了吓山每条路的路灯的控制权。hehe 蚤会进行若干次询问,每次询问时 hehe 蚤都会打开一部分路的路灯,并关闭剩下的路灯。当一条路上的路灯打开时,这条路就真实存在;当路灯关闭时,这条路就会 “神隐”,等效于不存在。
- 对于每个询问,hehe 蚤的小伙伴们都会进行一番实地考察,告诉 hehe 蚤吓山在当前状态下的哪些节点是可以通过道路相互连通的。
- 最后 hehe 蚤会根据询问结果总结出一份地图,即恢复出这棵树的形态。
为了更高效地解决问题,hehe 蚤将其抽象为了一道交互题。有一棵未知的树,你需要对交互库进行若干次询问,来恢复这棵树的形态。每次询问时,你需要给出一个长度为 \(n - 1\) 的 \(01\) 向量 \(A\),然后交互库会将每条满足 \(A_i = 1\) 的边 \((u_i, v_i)\) 加入一张新的空图 \(G\) 中,并返回其中每一个连通块(再删除这个图)。最后,你需要输出这棵树的所有边(顺序、方向任意)。
\(\mathbf{Part. 1}\)
我们定义 \(e_x\) 表示第 \(x\) 条边。我们说 \(e_x\) 连接的两个连通块分别为 \(S_x, T_x\)(如下图)。
我们考虑观察每条边需要的询问信息。如果说对于一个询问,第 \(x\) 条边存在,则 \(u\) 和 \(v\) 在同一连通块内;第 \(x\) 条边不存在,则 \(u\) 和 \(v\) 不属于同一连通块内。考虑哪一种情况信息更多。
- 对于第 \(x\) 条边存在的所有询问,假设询问集为 \(Q\)。对于这些询问,我们只知道 \(x\) 在分别每个询问中不可能连接哪些点。我们可以尝试保证在这些询问中,除 \(e_x\) 外每条边都至少不存在一次1。显然,只有 \((u, v)\) 这一个点对对于所有询问,\(u, v\) 都一直在同一连通块中。
- 对于第 \(x\) 条边不存在的所有询问,假设询问集为 \(Q\)。对于这些询问,我们只知道 \(x\) 在分别每个询问中可能连接哪些点。我们可以尝试保证在这些询问中,除 \(e_x\) 外每条边都至少存在一次。对于 \(a\in S_x, b\in T_x\),都有 \((a,b)\) 点对,对于所有相关询问,\(u, v\) 不属于同一连通块(但是 \((a,b)\) 不一定是一条边,它可以是一条路径)。
综上,列出上述两种情况的结论:
- 只有 \((u, v)\) 这一个点对,对于所有 \(x\) 边存在的询问,\(u, v\) 一直在同一连通块中,此时第 \(x\) 条边连接 \(u, v\)。
- 对于 \(a\in S_x, b\in T_x\),对于所有 \(x\) 边消失的询问,\((a, b)\) 不在同一连通块。此时,我们无法区分 \((a, b)\) 和真正的 \(u, v\)。
显然,第一种会更强。于是考虑分析第一种情况。
PS:实际上,第二种情况也可以做出这道题。
由 1 处,我们需要对于所有边 \(x\),在 \(x\) 存在的询问中,边 \(y\) 至少消失一次。因此,我们要考虑构造每个边 \(x\) 存在的询问集合 \(Q_x\),使得对于任意 \(i\neq j\),都有 \(Q_{i} \not\subseteq Q_j\)。(因为如果 \(Q_j \subseteq Q_i\),则 \(e_i\) 要么在 \(Q_j\) 中全部出现,要么在 \(Q_i\) 中存在询问没有出现)
这是一个经典问题,\(\binom{\text{limit}}{\frac{\text{limit}}{2}}\) 为最大值。具体见 CF1365G Secure Password 的 \(\mathbf{Part. 2}\)。复杂度瓶颈在于计算每条边是否一直在同一连通块,\(\mathcal{O}(n^2 \times \text{limit})\)。
\(\mathbf{Part. 2}\)
我们发现,如果想要去直接优化复杂度瓶颈,那将会非常困难,因为每一个可能的点对 \((u, v)\) 我们都要判断它可不可能是真的边。光是点对数量就有 \(\mathcal{O}(n^2)\) 个。
那优化方法显而易见:我们能不能对于点对分组,每次判断一个组内的点对,来减少计算量?这要求对于一个组内的点对可以一起判断,而且不能说存在 \(100\) 条边合法之类的事情发生。最好的话,我们要让同一组内合法的点对尽量少,比如说只有一个?
考虑按照点来对点对进行分组。对于第 \(x\) 个点,我们要一起判断对于所有 \(i \neq x\),\((x, i)\) 这个点对是否是真的边。显然,对于第 \(x\) 个点,存在 \(deg_x\) 个点对合法,而这个 \(deg_x\) 可能很大,比如菊花图。当然,\(deg_x\) 一定存在点非常小,树的叶子就一定是 \(1\)。
显然,一上来不可能去考虑 \(deg_x\) 很大的情况。通过化繁为简的思想,我们先从简单的情况入手,考虑寻找哪些分组只有一个合法点对。
假设我们当前在考虑 \(x\)。那么,如果它只有一个合法点对,说明 \(x\) 为叶子节点,而连接这个叶子节点的边则是合法点对。显然,当这条边存在时,考虑观察 \(x\) 所在的连通块大小,显然,肯定一直 \(> 1\)。但是当这条边不存在时,\(x\) 所在连通块大小永远为 \(1\),而这是非叶子节点做不到的(这时候,性质对象从边变成了点,所以计算量减少一个量级)。
因此,考虑维护每个点在所有询问中的连通块大小的情况。显然,在判断完最简单的叶子后,我们类似于 topo 排序把叶子删除,同时更新相邻点的连通块大小信息。一直剥叶子,化繁为简,即可通过这道题目。复杂度为 \(\mathcal{O}(n\times \text{limit}) = \mathcal{O}(n \log n)\)。
\(\mathbf{Part. +\infin}\)
这一部分是更新部分。
其实上面的方法是有漏洞的,我们不知道每个点的父亲节点!这样我们完全不能输出这颗树,而且这个还不是很好求。但是由于前面剥叶子的做法我们只需要删掉这个点,对于每个询问更新信息,是不需要知道每个点的父亲节点的,所以原树的拓扑序我们还是能求出来的。
那我们现在有什么信息?我们知道每个点所在的连通块信息,且知道每个点的拓扑序。
假设当前我们在计算第 \(x\) 个节点的父亲节点。\(x\) 所在的所有连通块中,深度最低的点(也是所有点的 LCA)显然是 \(x\) 的祖先。 而由于 1,在 \((x, fa_x)\) 这条边存在时,\((fa_x, fa_{fa_x})\) 肯定消失过至少一次。所以,肯定有一个 \(x\) 所属的连通块,这个连通块的 LCA 是 \(fa_x\)。因此,考虑对于所有连通块,寻找除了 LCA 为 \(x\) 的其他 LCA 深度最大的那个点。
但是我们不知道深度。怎么办呢?由于 \(x\) 所在的所有连通块,LCA 都是 \(x\) 的祖先,又由于有祖先关系的两个点,他们的深度关系可以通过拓扑序来判断,所以我们把深度改成拓扑序即可,寻找除了 LCA 为 \(x\) 的其他 LCA 拓扑序最小值,其中 LCA 是连通块中拓扑序的最大值。
UNR 6. D2T2 神隐的更多相关文章
- 使用极光/友盟推送,APP进程杀死后为什么收不到推送(转)
为什么会存在这样的 问题,刚开始的时候我也搞不清楚,之前用极光的时候杀死程序后也会收到推送,但最近重新再去集成时就完全不好使了,这我就纳闷了,虽然Google在高版本上的android上面不建议线程守 ...
- [zt]给你的Mp4大换血,精选Touch里3年收集的900多首歌,"经典不忍去的""最新近流行的",与你共享~~
如果你是音乐爱好者: 这些歌, 请戴上耳机, 调大音量, 一个人听 ,全世界 都是你的!!!!! (一)这些歌很温暖,没有金属味,适合有阳光的午后,很悠闲... [Anaesthesia]Maximi ...
- FILEtoJPG-神秘文件 -更新(软件BUG及建议可以在这里反馈)
FILEtoJPG-神秘文件(文件神隐助手) 论坛神器!彩虹系列作品之神秘文件(文件神隐助手),帮你隐藏文件的好帮手! 已更新,移除对winRAR的依赖 放张大图镇帖: 此图略丑,但是很有用,文末告诉 ...
- python爬虫抓取豆瓣电影
抓取电影名称以及评分,并排序(代码丑炸) import urllib import re from bs4 import BeautifulSoup def get(p): t=0 k=1 n=1 b ...
- 一起学爬虫——通过爬取豆瓣电影top250学习requests库的使用
学习一门技术最快的方式是做项目,在做项目的过程中对相关的技术查漏补缺. 本文通过爬取豆瓣top250电影学习python requests的使用. 1.准备工作 在pycharm中安装request库 ...
- android极光杀掉程序收不到通知
http://docs.jpush.io/guideline/faq/#android 第三方系统收不到推送的消息 由于第三方 ROM 的管理软件需要用户手动操作 小米[MIUI] 自启动管理:需要把 ...
- 一款APP的交互文档从撰写到交付
我第一份工作的设计总监是前百度设计师,34岁,一线设计12年:今年聊天说转了产品总监,如今39岁还活跃在行业中…… 我第二份工作的部门总监是前腾讯工程师,38岁,一线开发14年:2年前在Q群里跟我们说 ...
- bs4——BeautifulSoup模块:解析网页
解析由requests模块请求到的网页 import requests from bs4 import BeautifulSoup headers = {'User-Agent': 'Mozilla/ ...
- android tcp通讯
Andoird TCP通讯 前言 最近在写一个即时通讯的项目,有一些心得,写出来给大家分享指正一下. 简单描述一下这个项目: 实时查询车辆运行状态的项目,走TCP通迅. 接口采用GZIP压缩. 后台是 ...
- 隐马尔科夫模型python实现简单拼音输入法
在网上看到一篇关于隐马尔科夫模型的介绍,觉得简直不能再神奇,又在网上找到大神的一篇关于如何用隐马尔可夫模型实现中文拼音输入的博客,无奈大神没给可以运行的代码,只能纯手动网上找到了结巴分词的词库,根据此 ...
随机推荐
- Python 面向对象 之 多继承 MRO
Python 面向对象 之 多继承 MRO 回顾 - 类继承 关于子类的继承. 即子类可以继承父类的所有 方法及属性, 当子类要添加新功能或修改父类方法是, 可以在 子类对私进行 重写 overwri ...
- TVM中的Compute操作
定义 TVM从Halide继承了计算与调度分离的思想,并在其内部重用了部分Halide的调度原语,也引入了一些新的调度原语,用于优化GPU和专用加速器性能. 先举个例子吧: import tvm fr ...
- TVM:TensorIR
TensorIR是一种用于深度学习的特定领域语言,主要有两个目的. 在各种硬件后端进行程序变换和优化的实现 用于自动张量化程序优化的抽象 import tvm from tvm.script.pars ...
- 使用 Python 接口编译和优化模型 (AutoTVM)
在本节,将介绍与TVMC相同的知识,但展示的是如何使用Python API来完成它.完成本节后,我们将使用适用于 TVM 的 Python API 来完成以下任务: 为TVM Runtime编译预训练 ...
- 定制Django的Tag和Filter(一)
1.在 app 目录下创建 templatetags 目录(目录名只能是 templatetags). 如: app/ __init__.py models.py templatetags/ __in ...
- 什么是FIPS 140-3?
什么是FIPS 140-3? FIPS 140-3是一项由NIST(National Institute of Standards and Technology)发布的针对加密模块安全要求的标准,英文 ...
- JAVAFx将后台报错信息导出到前台,方便用户联系技术人员
Alert alert = new Alert(Alert.AlertType.ERROR);alert.setTitle("错误");alert.setHeaderText(&q ...
- Spring Boot 整合ActiveMQ实现延时发现消息
生产者提供两个发送消息的方法,一个是即时发送消息,一个是延时发送消息.延时发送消息需要手动修改activemq目录conf下的activemq.xml配置文件,开启延时.本文中maven依赖文件和ap ...
- .tar.gz 软件压缩包打包 AppImage 指南
要想打包 AppImage 分3步走 生成 AppDir 拷贝资源及依赖文件 生成 AppImage 准备工作 下载打包工具 linuxdeploy appimagetool 下载/解压 好要打包的程 ...
- k8s servicemonitor 采集超时配置
背景说明 我们有时候在编写exporter时,其中某个采集的metrics接口获取数据很慢,可能需要达到10-20S,基于此种情况,如果我们按照ServiceMonitor默认的配置进行,这里默认sc ...