题目大意:构造出一个长度为 n 的排列,使得按照这个顺序构造出的二叉搜索树的高度为 k

题目分析:知道 n 的大小后不难算出其可以构造的二叉搜索树高度的可行范围,下限是一棵满二叉树,这个利用倍增很快就能找到,上限就是 n ,当且仅当这棵树退化为一条链时达到,如果在这个范围内是一定有解且可以构造的

考虑如何构造答案,首先我们先构造一棵有 n 个节点,高度为 k 的树,只需要先用 dfs 固定出一条长度为 k 的链保证其高度至少为 k ,然后再用 bfs 逐层加点即可,当构造出整棵树后,递归对其赋值即可,赋值策略也是根据二叉搜索树的性质来的,因为对于二叉搜索树的任意一个节点来说,其左子树的所有节点都一定小于当前节点的值,其右子树的所有节点都一定大于当前节点的值,所以当前节点的值就是:(当前区间的左端点 + 左子树的大小)

代码:

//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e5+100;int n,k;int son[N][2],cnt,rt,num[N<<1];void dfs(int &u,int dep)
{if(dep>k)return;u=++cnt;dfs(son[u][0],dep+1);
}void bfs()
{queue<int>q;q.push(rt);while(q.size()){if(cnt==n)break;int u=q.front();q.pop();if(!son[u][0])son[u][0]=++cnt;if(cnt==n)break;q.push(son[u][0]);if(!son[u][1])son[u][1]=++cnt;q.push(son[u][1]);}
}void dfs_size(int u)
{num[u]=1;if(son[u][0])dfs_size(son[u][0]);if(son[u][1])dfs_size(son[u][1]);num[u]+=num[son[u][0]]+num[son[u][1]];
}void print(int u,int l,int r)
{printf("%d ",l+num[son[u][0]]);if(son[u][0])print(son[u][0],l,l+num[son[u][0]]-1);if(son[u][1])print(son[u][1],l+num[son[u][0]]+1,r);
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);scanf("%d%d",&n,&k);int l=0,r=n;while((1<<l)-1<n)l++;if(k<l||k>r)return 0*puts("impossible");dfs(rt,1);bfs();dfs_size(rt);print(rt,1,n);return 0;
}

中石油训练赛 - Insertion Order(二叉搜索树+构造)相关推荐

  1. 天梯赛-是否完全二叉搜索树

    将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果. 输入格式: 输入第一行给出一个不超过20的正整数 ...

  2. 中石油训练赛 - Block(二维前缀和+思维)

    题目描述 Alice得到了一张由n×m个黑白像素点组成的图片,她想要压缩这张图片.压缩图片的过程如下: 1.首先,选择一个正整数k(k>1),将图片划分成若干个k×k的小块.如果n,m不能被k整 ...

  3. 中石油训练赛 - 独居(二分水题)

    题目描述 一只奶牛自己独居,它每天需要吃1个水果和花费X元交暖气费.现在奶牛家里有F个水果和D元.奶牛最多能独居多少天?奶牛可以去超市买水果,超市每个水果P元. 输入 多组测试数据. 第一行,一个整数 ...

  4. 中石油训练赛 - Swapity Swap(矩阵快速幂)

    题目描述 Farmer John's N cows (1≤N≤100) are standing in a line. The ith cow from the left has label i, f ...

  5. 中石油训练赛 - Gone Fishing(固定大小的圆可以覆盖最多的点)

    题目大意:在二维平面中给出 n 个点,再给出一个固定大小的圆,问如何放置这个圆可以使其覆盖最多的点 题目分析:首先不难想到一种 n^3 的做法,就是两层循环去枚举两个点,因为两个不同的点就可以确定下来 ...

  6. 中石油训练赛 - Trading Cards(最大权闭合子图)

    题目大意:给出 n 个卡片,可以自由买卖,且价格都是相同的,再给出 m 个集合,如果已经得到了其中一个集合中的卡片,那么可以获得该集合的收益,问如何操作可以使得收益最大化 题目分析:最大权闭合子图的模 ...

  7. 中石油训练赛 - Bouldering(最短路+剪枝)

    题目大意:给出一个 n * m 的矩阵,矩阵中有些许数字,两个数字之间的距离如果小于 r 的话就是可达,到达一个数字后会消耗数字对应的体力值,问从最下面的数字到最上面的数字的最短路是多少,必须要保证体 ...

  8. 中石油训练赛 - Cafebazaar’s Chess Tournament(FFT)

    题目大意:给出 n 个队伍,每个队伍有两个属性分别记为 a 和 b ,如果队伍 i 和队伍 j 比赛: a[ i ] > a[ j ] && b[ i ] > b[ j ] ...

  9. 中石油训练赛 - Watch Later(状压dp)

    题目链接:点击查看 题目大意: 给出一个长度为 n 的字符串,字符串中共有 k 种不同的字符,现在问删除掉所有字符的最小操作数,对于每种字符需要确定一个先后顺序,每次需要删除掉当前所有的这种字符才能去 ...

最新文章

  1. 处理字典值是把字典放内存还是用sql处理_SQL索引及其底层实现
  2. 汽车之家机器学习平台的架构与实践
  3. JavaScriptjQuery 基本使用
  4. VS中每次改代码后运行程序不更新,只有重新编译才生效。
  5. wpa_supplicant wifi密码错误检测
  6. Dynamics CRM On-Premise V9安装手记
  7. Mybatis 一对多关联查询collection用法
  8. PPT:A Lexicon-Based Graph Neural Network for Chinese NER
  9. 用户首选项NSUserDefaults
  10. 字符串对象的charAt函数存在的意义
  11. coreos安装php,window_win10系统运行wps无响应的解决方案,wps是我们在日常办公中经常会 - phpStudy...
  12. Docker大书房:什么是Docker?怎么用?
  13. 关于IEnumeratorT泛型枚举器 和 IEnumerableT
  14. Mac窗口小部件,原来还有这么多使用细节!
  15. 五个最佳编程文本编辑器
  16. C#-Windows计算器
  17. 路飞学城python电子书闲鱼_路飞学城-python开发集训-第一章之用户登录作业
  18. java微信新增永久素材_微信公众号开发之新增永久图文素材(十)
  19. win7右击应用程序资源管理器停止工作问题
  20. matplotlib如何绘制圆

热门文章

  1. 仪表仪器信息管理C语言,仪器仪表管理系统C语言课程实习报告
  2. Elastic-Job重要概念
  3. JMM如何解决顺序一致性问题-JMM层面的内存屏障
  4. 从ResultSet 说起
  5. keepAliveTime和线程工厂
  6. Hive的基本操作-自定义函数
  7. Nginx与Zuul之间区别
  8. MyBatis动态SQL-foreach-数组/List
  9. POI的入门:绘制图形
  10. springboot整合filter