【NOIP 模拟赛】改造二叉树 最长上升子序列
2024-08-25 22:56:18
这道题我一眼就以为是线段树优化dp并且有了清晰的思路但是发现,我不会线段树区间平移,我以为只是我不会,然而根本就不行........
正解是把序列排出来然后我们让他们减去他们的下标之后求最长上升子序列。
#include <cstdio>
#include <algorithm>
const int N=;
int n,a[N],b[N],ch[N][],len,pos[N],c[N],f[N];
void dfs(int x){
if(!x)return;
dfs(ch[x][]);
b[++len]=a[x];
dfs(ch[x][]);
}
inline int Min(int x,int y){
return x<y?x:y;
}
inline int Max(int x,int y){
return x>y?x:y;
}
inline bool comp(int x,int y){
return b[x]<b[y];
}
inline int get_Max(int x){
int ret=;
while(x){
ret=Max(ret,c[x]);
x-=x&(-x);
}
return ret;
}
inline void ins(int x,int y){
while(y<=len){
c[y]=Max(x,c[y]);
y+=y&(-y);
}
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=,x,y;i<=n;i++){
scanf("%d%d",&x,&y);
ch[x][y]=i;
}
dfs();
len=;
for(int i=;i<=n;i++)
b[i]-=i,pos[i]=i;
std::sort(pos+,pos+n+,comp);
for(int i=,last;i<=n;i++){
if(i==||b[pos[i]]!=last)
len++;
last=b[pos[i]];
b[pos[i]]=len;
}
int ans=;
for(int i=;i<=n;i++){
f[i]=get_Max(b[i])+;
ins(f[i],b[i]);
ans=Max(ans,f[i]);
}
printf("%d",n-ans);
}
最新文章
- Brackets前端开发IDE工具
- linux 登录档配置分析
- Mybatis错误(一)org.apache.ibatis.exceptions.PersistenceException
- 王高利:Linux__apache,安装,报错解决
- HDOJ 2544
- SqlSever基础 Upper函数 返回字符串的大写形式
- ps命令详解(转)
- free命令、buffer与cache的区别
- 关于oracle数据库(6)约束
- [java多线程] - Thread&;Runnable运用
- Eclipse+Spring+SpringMVC+Maven+Mybatis+MySQL+Tomcat项目搭建
- 通过接口标准化ABAP OO开发
- c#项目减少源代码大小
- Vue 使用swiper4导致ie或手机浏览器打开空白的问题
- 【读书笔记】iOS-移动开发
- ethereum/EIPs-158 State clearing 被EIP-161取代
- Tor源码阅读与改造(一)
- VS 统计整个项目总的代码行数
- git报错fatal: I don&#39;t handle protocol &#39;​https&#39;处理
- 《linux/unix设计思想》读后感