问题 C: 改造二叉树
时间限制: 1 Sec 内存限制: 128 MB题目描述
![](http://172.18.111.252/upload/image/20170812/20170812080419_23272.png)
输入
3
2 2 2
1 0
1 1
输出
2
提示
考试时居然有人看成了树规。。。把中序遍历搞出来就成了单调上升,但是单调不下降子序列最好求。。
新技巧:把a[i]-i.这样就变成单调不下降的了。
对n^2进行优化:记录长度为i的不下降的子序列最小a[i]进行记录,upper_bound进行查就行了。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define N 100000
#define inf 1000000000
using namespace std;
int read()
{
int sum=0,f=1;char x=getchar();
while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
while(x>='0'&&x<='9'){sum=(sum<<3)+(sum<<1)+x-'0';x=getchar();}
return sum*f;
}
int n,a[N+5],lc[N+5],rc[N+5],val[N+5],cnt;
int f[N+5],t[N+5];
void tree(int x)
{
if(lc[x])tree(lc[x]);
val[++cnt]=a[x];
if(rc[x])tree(rc[x]);
}
int main()
{
// freopen("binary18.in","r",stdin);
// freopen("binary.out","w",stdout);
n=read();
memset(t,120,sizeof(t));
for(int i=1;i<=n;i++)a[i]=read();
int x,y;
for(int i=2;i<=n;i++)
{
x=read();
y=read();
if(y==0)lc[x]=i;
else rc[x]=i;
}
tree(1);
int ans=0;
for(int i=1;i<=n;i++)val[i]-=i;
for(int i=1;i<=n;i++)
{
int k=upper_bound(t+1,t+n+1,val[i])-t;
f[i]=k;
ans=max(ans,f[i]);
t[k]=min(t[k],val[i]);
}//cout<<ans<<" ";
printf("%d\n",n-ans);
}