/*
根據(jù)題目的約束條件,可以對(duì)該樹(shù)進(jìn)行后序遍歷
然后對(duì)得到的序列進(jìn)行調(diào)整使得其成為符合約束條件的序列。
約束條件有:1,父親節(jié)點(diǎn)的key>=子孫的key;
2,左兒子的key<右兒子的key;
為使<關(guān)系變?yōu)?lt;= ,如a<b可以變?yōu)閍<=b-1
依據(jù)這樣子,所以每次發(fā)現(xiàn)<時(shí)可以-1,而這種情況是在遍歷右子樹(shù)時(shí)才會(huì)有<關(guān)系
根據(jù)題目的約束條件,可以對(duì)該樹(shù)進(jìn)行后序遍歷
然后對(duì)得到的序列進(jìn)行調(diào)整使得其成為符合約束條件的序列。
約束條件有:1,父親節(jié)點(diǎn)的key>=子孫的key;
2,左兒子的key<右兒子的key;
為使<關(guān)系變?yōu)?lt;= ,如a<b可以變?yōu)閍<=b-1
依據(jù)這樣子,所以每次發(fā)現(xiàn)<時(shí)可以-1,而這種情況是在遍歷右子樹(shù)時(shí)才會(huì)有<關(guān)系
若只有左孩子的時(shí)候,左孩子是可以與父親相等的
最后再求LIS nlogn
*/
#include<cstdio>
#include<cstring>
const int MAXN=1024*1024+10;
int a[MAXN],x[MAXN];
int n,h;
int delta,cnt;
void dfs(int hh,int p){
if(hh>h||p>n)return;
if(hh<h&&p+p<=n)dfs(hh+1,p+p);
if(hh<h&&p+p+1<=n){//every '<' +1
delta++;
dfs(hh+1,p+p+1);
}
x[++cnt]=a[p]-delta;//
}
int main(){
n=1;
scanf("%d",&h);
while(~scanf("%d",&a[n]))n++;
n--;delta=0;cnt=0;
dfs(1,1);
int len=0;
for(int i=1;i<=n;i++){
int low=1,high=len+1;
while(high>low){
int mid=(high+low)>>1;
if(a[mid]>x[i])high=mid;
else low=mid+1;
}
if(low==len+1)len++;
a[low]=x[i];
}
printf("%d\n",n-len);
return 0;
}
最后再求LIS nlogn
*/
#include<cstdio>
#include<cstring>
const int MAXN=1024*1024+10;
int a[MAXN],x[MAXN];
int n,h;
int delta,cnt;
void dfs(int hh,int p){
if(hh>h||p>n)return;
if(hh<h&&p+p<=n)dfs(hh+1,p+p);
if(hh<h&&p+p+1<=n){//every '<' +1
delta++;
dfs(hh+1,p+p+1);
}
x[++cnt]=a[p]-delta;//
}
int main(){
n=1;
scanf("%d",&h);
while(~scanf("%d",&a[n]))n++;
n--;delta=0;cnt=0;
dfs(1,1);
int len=0;
for(int i=1;i<=n;i++){
int low=1,high=len+1;
while(high>low){
int mid=(high+low)>>1;
if(a[mid]>x[i])high=mid;
else low=mid+1;
}
if(low==len+1)len++;
a[low]=x[i];
}
printf("%d\n",n-len);
return 0;
}