Codeforces 1129 E.Legendary Tree
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的更多相关文章
- Codeforces 461B Appleman and Tree(木dp)
题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...
- Codeforces 1129 D. Isolation
Codeforces 1129 D. Isolation 解题思路: 令 \(f(l,r)\) 为 \([l,r]\) 中之出现一次的元素个数,然后可以得到暴力 \(\text{dp}\) 的式子. ...
- Codeforces 280C Game on tree【概率DP】
Codeforces 280C Game on tree LINK 题目大意:给你一棵树,1号节点是根,每次等概率选择没有被染黑的一个节点染黑其所有子树中的节点,问染黑所有节点的期望次数 #inclu ...
- Codeforces A. Game on Tree(期望dfs)
题目描述: Game on Tree time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Codeforces Round #781(C. Tree Infection)
Codeforces Round #781 C. Tree Infection time limit per test 1 second memory limit per test 256 megab ...
- Codeforces 1129E - Legendary Tree(思维题)
Codeforces 题面传送门 & 洛谷题面传送门 考虑以 \(1\) 为根,记 \(siz_i\) 为 \(i\) 子树的大小,那么可以通过询问 \(S=\{2,3,\cdots,n\}, ...
- Codeforces.1129E.Legendary Tree(交互 二分)
题目链接 \(Description\) 有一棵\(n\)个点的树.你需要在\(11111\)次询问内确定出这棵树的形态.每次询问你给定两个非空且不相交的点集\(S,T\)和一个点\(u\),交互库会 ...
- Codeforces 734E. Anton and Tree 搜索
E. Anton and Tree time limit per test: 3 seconds memory limit per test :256 megabytes input:standard ...
- codeforces 161D Distance in Tree 树形dp
题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...
随机推荐
- 【BZOJ】2466: [中山市选2009]树 高斯消元解异或方程组
[题意]给定一棵树的灯,按一次x改变与x距离<=1的点的状态,求全0到全1的最少次数.n<=100. [算法]高斯消元解异或方程组 [题解]设f[i]=0/1表示是否按第i个点的按钮,根据 ...
- UIWebView---iOS-Apple苹果官方文档翻译
CHENYILONG Blog UIWebView---iOS-Apple苹果官方文档翻译 UIWebView 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博h ...
- oozie与sqoop的简单案例
1:拷贝模板 2:拷贝hive用的jar包 方式一: 3:编辑job.properties # # Licensed to the Apache Software Foundation (ASF) u ...
- Sublime快捷键(一)
最近在工作中,遇到的sublime的快捷键,以后再工作中用到的我会稍后增加的~ 快捷键: 1.切换标签页: Ctrl + Tab 切换标签页: Ctrl + Shift + Tab 返回刚切 ...
- 爬虫实战--使用Selenium模拟浏览器抓取淘宝商品美食信息
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.common.exce ...
- nfs服务器配置
安装 nfs-utils,该软件包提供了 NFS 工具: # yum install nfs-utils 配置启动脚本,使得共享在系统每次启动时都有效: # chkconfig --add rpcbi ...
- Ubuntu每次开机后提示:检测到系统程序出现问题的解决方法
首先,错误报告存放位置: cd /var/crash/ ls //可以查看错误报告 1 2 sudo rm /var/crash/* //删除该目录下的所有文件 1 但是,这只是删除掉的是错误报告,如 ...
- SYN Flood攻击及防御方法 (转)
原文连接:http://blog.csdn.net/bill_lee_sh_cn/article/details/6065704 一.为什么Syn Flood会造成危害 这要从操作系统的TC ...
- C语言使用数学库编译不通过问题
#include <stdio.h>#include <math.h> int main(){ double a = 10.0,b = 3.0; f ...
- P1084 疫情控制
Solution 二分答案, 尽量往上跳, 不能跳到根节点. 仍然能跳的拿出来.看剩下的点没有覆盖哪个? 贪心的分配一下. Code 70 #include<iostream> #incl ...