改造二叉树
![](http://172.18.111.252/upload/image/20170812/20170812080419_23272.png)
输入
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; }