找了老半天错误。。

高度为i的平衡树至少要有f(i)=f(i-1)+f(i-2)+1个结点
从小到达枚举i,如果i被选中,那么其所有祖先p也必被选中
考虑i能否加入:如果i在祖先p的左子树里,p的左子树高度更新,连带更新右子树必须要有的高度
如果i在组先p的右子树里,更新右子树高度,只要右子树高度<=左子树高度+1即可

/*
高度为i的平衡树至少要有f(i)=f(i-1)+f(i-2)+1个结点
从小到达枚举i,如果i被选中,那么其所有祖先p也必被选中
考虑i能否加入:如果i在祖先p的左子树里,p的左子树高度更新,连带更新右子树必须要有的高度
          如果i在组先p的右子树里,更新右子树高度,只要右子树高度<=左子树高度+1即可 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 600005

int ans[N],k,n,mi[N],ls[N],rs[N],fa[N],dl[N],d[N];

void dfs(int u){
    if(ls[u]){
        d[ls[u]]=d[u]+1;
        dfs(ls[u]);
    }
    if(rs[u]){
        d[rs[u]]=d[u]+1;
        dfs(rs[u]);
    }
}

int main(){
    mi[1]=1;mi[2]=2;
    for(int i=3;i<=3000;i++)
        mi[i]=mi[i-1]+mi[i-2]+1;
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>fa[i];
        if(fa[i]!=-1){
            if(i<fa[i])ls[fa[i]]=i;
            else rs[fa[i]]=i;
        }
    }
    
    int root;
    for(int i=1;i<=n;i++)if(fa[i]==-1)root=i;
    dfs(root);
    
    for(int i=1;i<=n;i++)if(!ans[i]){
        int pre=fa[i],now=i,tot=k;
        while(pre!=-1){
            if(!ans[pre])tot--;//祖先没被选过 
            if(now==ls[pre]){//now是pre左子树 
                int t=d[i]-d[pre];
                if(dl[pre]<t)
                    tot-=mi[t-1]; 
                else tot-=mi[dl[pre]-1];
            }else{//now是pre右子树 
                if(!ans[pre]){tot=-1;break;}
                int t=d[i]-d[pre];
                if(t>dl[pre]+1){tot=-1;break;} 
            }
            now=pre;pre=fa[now];
        }
        if(tot>=1){
            ans[i]=1;k--;
            int pre=fa[i],now=i;
            while(pre!=-1){
                if(!ans[pre])ans[pre]=1,k--;
                if(now==ls[pre]){
                    int t=d[i]-d[pre];
                    if(dl[pre]<t){
                        dl[pre]=t;
                    }
                }
                now=pre;pre=fa[pre];
            }
        }else {
            ans[i]=0;
        }
    }
    
    for(int i=1;i<=n;i++)cout<<ans[i];
    
} 
View Code

相关文章:

  • 2021-08-19
  • 2021-08-19
  • 2022-12-23
  • 2021-08-21
  • 2021-06-21
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-12-15
  • 2021-11-23
  • 2021-09-30
  • 2022-12-23
  • 2022-12-23
  • 2021-05-18
相关资源
相似解决方案