改造二叉樹

輸入

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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章