[noip模拟]改造二叉树<LIS>
1.改造二叉树
【题目描述】
小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树。通常子结点被称作“左孩子”和“右孩子”。二叉树被用作二叉搜索树和二叉堆。随后他又和他人讨论起了二叉搜索树。
什么是二叉搜索树呢?二叉搜索树首先是一棵二叉树。设key[p]表示结点p上的数值。对于其中的每个结点p,若其存在左孩子lch,则key[p]>key[lch];若其存在右孩子rch,则key[p]<key[rch];注意,本题中的二叉搜索树应满足对于所有结点,其左子树中的key小于当前结点的key,其右子树中的key大于当前结点的key。
小Y与他人讨论的内容则是,现在给定一棵二叉树,可以任意修改结点的数值。修改一个结点的数值算作一次修改,且这个结点不能再被修改。若要将其变成一棵二叉搜索树,且任意时刻结点的数值必须是整数(可以是负整数或0),所要的最少修改次数。
相信这一定难不倒你!请帮助小Y解决这个问题吧。
【输入格式】
第一行一个正整数n表示二叉树结点数。结点从1~n进行编号。
第二行n个正整数用空格分隔开,第i个数ai表示结点i的原始数值。
此后n - 1行每行两个非负整数fa, ch,第i + 2行描述结点i + 1的父亲编号fa,以及父子关系ch,(ch = 0 表示i + 1为左儿子,ch = 1表示i + 1为右儿子)。
结点1一定是二叉树的根。
【输出格式】
仅一行包含一个整数,表示最少的修改次数。
【样例输入】
3
2 2 2
1 0
1 1
【样例输出】
2
【数据范围】
20 % :n <= 10 , ai <= 100.
40 % :n <= 100 , ai <= 200
60 % :n <= 2000 .
100 % :n <= 10 ^ 5 , ai < 2 ^ 31.
对树的知识了解的人可能一下就可以反应过来,我们针对一个小的分支看,是左边<父节点<右边。。。。然后这个顺序想到了啥
对,就是中序遍历,中序遍历:左中右。。。。然后题中也说到,整个左子树要小于父节点
然后我们就能够推出来,改造二叉树的中序遍历是严格上升的
然后题就转换成了求中序遍历,然后求最长严格上升子序列。。。。
求最长严格上升子序列可以进行优化,因为是严格上升,所以第i个至少比第i-1个大1,然后我们可以对这个序列里的数减去他的序数,就是求最长不下降子序列
这题还有一个需要注意的地方是,数据范围太大,不适合普通的LIS做法,要进行优化。。。
优化方式是开个数组f[i]记录满足条件的第i个数最小是f[i]
我们画图理解

然后我们唯一要处理就是图中第一个6和4 对f的影响
这里我们可以用二分的方式,因为是上升子序列,所以我们只需要二分找到第一个比当前小的数,然后用当前数取代之前那个数
图中就是,当i=4时,二分找到第一个比他小的i=1,a[i]=1的数,然后发现a[2]<a[4]就用2取代这个位置的6,f[2]=6,9的取代同理
这样做就大大优化了时间,不会超时
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<queue>
#define maxn 100005
using namespace std; struct node{
int l,r,val;
}tree[maxn]; int n,a[maxn],f[maxn],ans,tot; void dfs(int pos){//中序遍历左中右
if(pos<)return;
dfs(tree[pos].l);
tot++;
a[tot]=tree[pos].val-tot;//求最长不下降子序列
dfs(tree[pos].r);
} int find(int l,int r,int x)
{
while(l<=r){
int mid=(l+r)/;
if(f[mid]<=x)l=mid+;
else r=mid-;
}
return l;
} int main()
{
freopen("binary.in","r",stdin);
freopen("binary.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&tree[i].val);
}int fa,so;
for(int i=;i<=n;i++){
scanf("%d%d",&fa,&so);
if(so==)tree[fa].l=i;
else tree[fa].r=i;
}
dfs();
f[]=a[];ans=;
for (int i=;i<=n;i++)//最长不降字串一类的信方式
{
if (a[i]>=f[ans])
f[++ans]=a[i];
else
f[find(,ans,a[i])]=a[i];//当合法字串长度一样,尽量用小的那一个
}
printf("%d\n",n-ans);
/*
6
4 6 5 1 9 6
1 0
1 1
2 0
2 1
3 1
*/
}
总结:在遇到和树相关的题时,如果允许,可以从前中后遍历去查询问题。。。
最长上升或不降这一类的题,可以进行优化,优化方式如文。。。
还有一点就是可以合理运用容斥原理,我们这是求最少不合法的个数,然后可以转换成总数减去合法的最大个数
[noip模拟]改造二叉树<LIS>的更多相关文章
- 改造二叉树 (长乐一中模拟赛day2T1)
1.改造二叉树 [题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随 ...
- 10.26最后的模拟DAY2 改造二叉树[中序遍历+严格递增的最长不下降子序列]
改造二叉树 [题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随后他 ...
- CH Round #49 - Streaming #4 (NOIP模拟赛Day2)
A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...
- Nescafe #29 NOIP模拟赛
Nescafe #29 NOIP模拟赛 不知道这种题发出来算不算侵权...毕竟有的题在$bz$上是权限题,但是在$vijos$似乎又有原题...如果这算是侵权的话请联系我,我会尽快删除,谢谢~ 今天开 ...
- NOI.AC NOIP模拟赛 第五场 游记
NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...
- NOI.AC NOIP模拟赛 第六场 游记
NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...
- 2014-10-31 NOIP模拟赛
10.30 NOIp 模拟赛 时间 空间 测试点 评测方式 挖掘机(dig.*) 1s 256M 10 传统 黑红树(brtree.*) 2s 256M 10 传统 藏宝图(treas. ...
- 20190908 NOIP 模拟40
考试过程: 刚看完题,发现T1是个类lis 问题,但要求$O(nlogn)$,应该是个数据结构优化dp,T2应该是个数据结构,T3是个字符串?没有匹配,不会是后缀数组吧,这是NOIP模拟啊,可能是个d ...
随机推荐
- C/C++ 手动开O2
手动O2比赛不能用,平时玩玩就好 #pragma GCC optimize (2) #pragma G++ optimize (2)
- Pytorch-Tensor基本操作
(此文为个人学习pytorch时的笔记,便于之后的查询) Tensor基本操作 创建tensor: 1.numpy向量转tensor: a=np.array([2,2,2]) b=torch.fr ...
- Oracle批量插入有日期类型数据
例如现在有张表 id(number) startTime(date) name(varchar2) 1 2017-08-13 zhangsan 2 2017-08-14 zhangsan 需要批量 ...
- Drf 序列化 ModelSerializer跨表取数据
1.对于OneToOne.Foreignkey.choices字段可以使用source取出相关信息: class CourseSerializer(serializers.ModelSerialize ...
- go源码分析(五) 获取函数名和调用者的函数名
参考资料 实现代码保存在我的github // input flag 1:FunName 2:CallerFunName func GetFuncName(flag int) string { ...
- react build本地相对目录 "homepage": ".", package.json
react build相对目录 "homepage": ".", package.json
- linux 执行计划任务crontab
crontab 一些常用的命令 service crond start //启动服务 service crond stop //关闭服务 service crond restart //重启服务 se ...
- Lambda表达式学习笔记
Lambda基础语法 Java8中引入了一个新的操作符" -> ",该操作符被称为箭头操作符或Lambda操作符,箭头操作符将Lambda表达式拆分成两部分: 左侧:Lamb ...
- ngzorro draw 第一次打开 ERROR TypeError: Cannot read property 'overlayElement' of undefined
at NzDrawerComponent.push../node_modules/ng-zorro-antd/fesm5/ng-zorro-antd.js.NzDrawerComponent.trap ...
- Spring框架——IOC 容器的创建与使用
企业级开发框架 Spring Framework 是整个 Spring 生态的基础,各个模块都是基于 Spring Framework 衍生出来的. Spring 的两大核心机制 IOC 控制翻转.A ...