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. 服务器端包含 SSI简介

    服务器端包含 SSI,是英文 Server Side Includes的简写.SSI是一种可以指挥服务器动态声称网页内容的HTML指令. 通常SSI可以用来确保网页中的一些通用内容,比如版权信息.联系 ...

  2. docker使用现有容器生成新的镜像

    /*运行docker run后 --则进入该容器里了 我们做一些变更,比如安装一些东西 ,然后针对这个容器进行创建新的镜像 */ 基本形式: docker commit -m "change ...

  3. Coursera在线学习---第一节.梯度下降法与正规方程法求解模型参数比较

    一.梯度下降法 优点:即使特征变量的维度n很大,该方法依然很有效 缺点:1)需要选择学习速率α 2)需要多次迭代 二.正规方程法(Normal Equation) 该方法可以一次性求解参数Θ 优点:1 ...

  4. 用C#实现对MSSqlServer数据库的增删改查---DAL层

    说明:本人完成的工作是对传感器--超声波物位计进行硬件集成,上位机通过串口接收传感器数据并将其存到数据库中:在DAL层实现对数据库的增删改查,其中包含两个数据表分别是WaterLevelSet表和Wa ...

  5. Hashtable之Properties

    properties的使用:1.Hashtable的实现类,线程安全.与HashMap不同,Hashtable不允许使用null作为key和value2.和HashMap一样,Hashtable也不能 ...

  6. 修改vs17中的cordova模板

    因为visual studio 2017创建的默认cordova-ios的版本自动编译带有swift语言的插件会出现异常,cordova-ios升级到4.3.1,并且配置build.json能解决问题 ...

  7. Ubuntu或者Ubuntu server重新设置IP地址

    1.打开终端输入: sudo vi /etc/network/interfaces 2.进入编辑页面 改一处,添加5行内容,如下图: 3.修改好后esc    :wq进行保存 4.输入: sudo / ...

  8. 手游研发CJ抱大腿指南

    文摘要:CJ来了,又是一年一度的游戏圈盛事,随着手游行业的迅速崛起,今年CJ上,手游研发商以及发行商必定成为焦点.由于门槛低.市场热.前景好等因素的影响,国内一下子蹦出一大堆手游研发团队.很幸运(或者 ...

  9. hdu 5875(单调栈)

    Function Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  10. hdu 1847(SG函数,巴什博弈)

    Good Luck in CET-4 Everybody! Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...