Codeforces 1129 E.Legendary Tree

解题思路

这题好厉害,我来复读一下官方题解,顺便补充几句。

首先,可以通过询问 \(n-1​\) 次 \((S=\{1\},T=\{2\dots n\},i),i\in[2,n]​\) ,来得到以 \(1​\) 为根树的所有节点的子树大小。

然后考虑从子树大小最小的节点开始,为每一个节点找它们的儿子,由于每个节点儿子的子树大小,一定小于这个节点的子树大小,所以可以按照子树大小从小到大排序,每个节点的儿子就一定在其前面。

假设已经找到了一个节点的儿子,那么考虑把这个节点当前找到的这个儿子在序列中删除,对于序列中在其后面的那个节点来说,其前面除了它的儿子以为所有点都不在它的子树中。

那么对于当前做到的序列的第 \(x\) 个位置,可以二分一个位置 \(mid\) ,询问 \((S=\{1\},T=\{a_1\dots a_{mid}\},x)\) ,第一个返回结果不是 \(0\) 的 \(mid\) 一定 \(x\) 的儿子,这样重复做下去直到还原总询问次数是 \(O(n-1+(n-1)logn)\)。

code

/*program by mangoyang*/
#pragma GCC optimize("inline", "Ofast")
#include <bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 1005;
vector<int> S, T;
vector<pair<int, int> > Edge;
int sz[N], a[N], del[N], n;
inline int query(vector<int> S, vector<int> T, int x){
printf("%d\n", (int) S.size());
for(int i = 0; i < (int) S.size(); i++)
printf("%d ", S[i]);
printf("\n%d\n", (int) T.size());
for(int i = 0; i < (int) T.size(); i++)
printf("%d ", T[i]);
printf("\n%d\n", x);
fflush(stdout);
int ans = 0;
return read(ans), ans;
}
inline bool cmp_size(int x, int y){
return sz[x] < sz[y];
}
inline int check(int mid, int x){
T.clear();
for(int i = 1; i <= mid; i++)
if(!del[i]) T.push_back(a[i]);
if(!(int)T.size()) return 0;
return query(S, T, x) > 0;
}
int main(){
read(n);
S.push_back(1);
for(int i = 2; i <= n; i++) T.push_back(i);
sz[1] = n;
for(int i = 2; i <= n; i++)
sz[i] = query(S, T, i);
for(int i = 1; i <= n; i++) a[i] = i;
sort(a + 1, a + n + 1, cmp_size);
for(int i = 1; i < n; i++){
int u = a[i];
if(sz[u] == 1) continue;
while(1){
int l = 1, r = i - 1, pos = -1;
while(l <= r){
int mid = (l + r) >> 1;
if(check(mid, u)) pos = mid, r = mid - 1;
else l = mid + 1;
}
if(pos == -1) break;
del[pos] = 1;
Edge.push_back(make_pair(u, a[pos]));
}
}
for(int i = 1; i < n; i++)
if(!del[i]) Edge.push_back(make_pair(a[i], 1));
puts("ANSWER");
for(int i = 0; i < (int) Edge.size(); i++)
printf("%d %d\n", Edge[i].first, Edge[i].second);
fflush(stdout);
return 0;
}

Codeforces 1129 E.Legendary Tree的更多相关文章

  1. Codeforces 461B Appleman and Tree(木dp)

    题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...

  2. Codeforces 1129 D. Isolation

    Codeforces 1129 D. Isolation 解题思路: 令 \(f(l,r)\) 为 \([l,r]\) 中之出现一次的元素个数,然后可以得到暴力 \(\text{dp}\) 的式子. ...

  3. Codeforces 280C Game on tree【概率DP】

    Codeforces 280C Game on tree LINK 题目大意:给你一棵树,1号节点是根,每次等概率选择没有被染黑的一个节点染黑其所有子树中的节点,问染黑所有节点的期望次数 #inclu ...

  4. Codeforces A. Game on Tree(期望dfs)

    题目描述: Game on Tree time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  5. Codeforces Round #781(C. Tree Infection)

    Codeforces Round #781 C. Tree Infection time limit per test 1 second memory limit per test 256 megab ...

  6. Codeforces 1129E - Legendary Tree(思维题)

    Codeforces 题面传送门 & 洛谷题面传送门 考虑以 \(1\) 为根,记 \(siz_i\) 为 \(i\) 子树的大小,那么可以通过询问 \(S=\{2,3,\cdots,n\}, ...

  7. Codeforces.1129E.Legendary Tree(交互 二分)

    题目链接 \(Description\) 有一棵\(n\)个点的树.你需要在\(11111\)次询问内确定出这棵树的形态.每次询问你给定两个非空且不相交的点集\(S,T\)和一个点\(u\),交互库会 ...

  8. Codeforces 734E. Anton and Tree 搜索

    E. Anton and Tree time limit per test: 3 seconds memory limit per test :256 megabytes input:standard ...

  9. codeforces 161D Distance in Tree 树形dp

    题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...

随机推荐

  1. AutoESL与Xilinx那些人和事

    大年三十,看到Xilinx收购AutoESL的新闻, 顿时觉得今年特别喜庆,于是,连春晚也懒得骂了. 本想立即写一篇博文八卦一番, 怎奈亲朋好友饭局不断,一直拖到今天才动笔. 与一年前Xilinx宣布 ...

  2. GD库imagecopyresampled()方法详解~

    整理了一下GD库这个缩放,拉伸复制的方法 因为这个函数参数太多了~ imagecopyresampled()   /* //拷贝部分图像并调整大小 bool imagecopyresampled ( ...

  3. 爬虫实战--利用Scrapy爬取知乎用户信息

    思路: 主要逻辑图:

  4. 爬虫--Scrapy框架的基本使用

    流程框架 安装Scrapy: (1)在pycharm里直接就可以进行安装Scrapy      (2)若在conda里安装scrapy,需要进入cmd里输入指令conda install scrapy ...

  5. FPGA与CPLD的概念及其区别

    一.FPGA与CPLD的基本概念 1.CPLD CPLD主要是由可编程逻辑宏单元(LMC,Logic Macro Cell)围绕中心的可编程互连矩阵单元组成,其中LMC逻辑结构较复杂,并具有复杂的I/ ...

  6. JS时间转换的一个坑位

    在做项目的时候,无意发现了一个小东西. new Date('2018-05-15') new Date('2018-5-15') 输出的结果是不同的,相差了8小时.然后让我回忆到之前看的一个时间转换函 ...

  7. easyui datagrid 去掉 全选checkbox

    在加载 表格的时候添加事件:onLoadSuccess 在事件中写入下面句,用空代替原有HTML 达到取消效果. $(".datagrid-header-check").html( ...

  8. 大数据系列之kafka监控kafkaoffsetmonitor安装

    1.下载kafkaoffsetmonitor的jar包,可以到github搜索kafkaoffsetmonitor,第一个就是,里面可以下载编译好了的包. KafkaOffsetMonitor-ass ...

  9. Windows下Oracle数据库自动备份批处理脚本

    expdb命令版本 @echo off REM ########################################################### REM # Windows Se ...

  10. Python连接Access数据库

    前言 今天想要用Python访问Access数据库,折腾了半天,特记录一下 背景 最近想将一些文件记录下来,存入数据库,为此拿LabVIEW写了一个版本,记录环境配置为: LabVIWE:2015 A ...