改造二叉树

输入

3

2 2 2

1 0

1 1

输出

2

提示

二叉搜索树的中序遍历是一个从小到大的序列,先先中序遍历得到新的序列b[i],然后对于j>=i,需要满足f[j]-f[i]>=j-i  即f[j]-j>=f[i]-i;然后规定g[i]=f[i]-i;那么不用变换的位置g[i]呈不下降序列,求出g[i]的最长不下降序列,然后用n-len

#include<iostream>
#include<cstdio>
#include<cstring>
#define LL long long
#define maxn 100005
using namespace std;
int n,cnt=0;
LL f[maxn],g[maxn],Maxl;
int fa[maxn],son[maxn][3];
LL a[maxn],b[maxn];
bool w[maxn];
void dfs(int x)
{
    if(!x) return ;
    dfs(son[x][0]);
    b[++cnt]=a[x]; 
    dfs(son[x][1]);
}
inline LL getmax(LL x)
{
   for(int i=Maxl;i>=0;i--)
   if(b[g[i]]<=x) return i;
   return 0;         
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int i=2;i<=n;i++){
       scanf("%d%d",&fa[i],&w[i]);
       son[fa[i]][w[i]]=i;
    }
    dfs(1);
    for(int i=1;i<=n;i++)  b[i]=b[i]-(LL)i;
    for(int i=1;i<=n;i++){
       f[i]=getmax(b[i])+1;
       if(g[f[i]]==0) g[f[i]]=i;
       else if(b[i]<b[g[f[i]]])  g[f[i]]=i;
       Maxl=max(Maxl,f[i]);
    }
    LL ans=0;
    for(int i=1;i<=n;i++) ans=max(ans,f[i]);
    printf("%d\n",n-ans);
    return 0;
}


posted @ 2017-08-12 21:39  HunterxHunterl  阅读(138)  评论(0编辑  收藏  举报