D e s c r i p t i o n Description Description
给定一棵树,求将其改为 B S T BST BST的最少修改点数(只能改为整数)
数据范围: n ≤ 1 0 6 n\leq 10^6 n≤106
S o l u t i o n Solution Solution
B S T BST BST有一个性质,那就是它的中序遍历一定是有序的,据此性质,我们先求出原树的中序遍历,然后求 L I S LIS LIS即可
需要注意的是,由于边权要求改为整数,所以会出现少算的情况,因此,我们对中序遍历为 i i i的数 x x x统一减去 i i i即可,这样就满足了要求
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
C o d e Code Code
#include<cstdio>
#include<algorithm>
using namespace std;int n,x,lson[1000001],rson[1000001],dfn[1000001],y,m,b[1000001],f[1000001],ans,a[1000001];
inline void dfs(int x)
{
if(!x) return;
dfs(lson[x]);
dfn[++m]=a[x]-m;
dfs(rson[x]);
return;
}
signed main()
{
scanf("%d",&n);
for(register int i=1;i<=n;i++) scanf("%d",&a[i]);
for(register int i=2;i<=n;i++) {scanf("%d%d",&x,&y);if(!y)lson[x]=i;else rson[x]=i;}
dfs(1);
f[ans=1]=dfn[1];
for(register int i=2;i<=n;i++)
{
if(dfn[i]>=f[ans]) f[++ans]=dfn[i];
else *upper_bound(f+1,f+1+ans,dfn[i])=dfn[i];
}
printf("%d",n-ans);
}