堆+思维——cf1330E

/*
如果堆的绝对高度>g,那么这个堆还可以继续删点;反之不能继续删点 
层序遍历堆,按上述方法不断删点直到该点不能再删后,到下一个结点去删 
ps:记得一定要把a数组初始化了!
*/ #include<bits/stdc++.h> using namespace std; #define N 2300005 #define ll long long int n,h,g,a[N]; vector<int>ans; void del(int rt){ int lv=a[rt<<1],rv=a[rt<<1|1]; if(lv==0 && rv==0){ a[rt]=0; }else if(lv>=rv){//找大的删 a[rt]=a[rt<<1]; del(rt<<1); }else { a[rt]=a[rt<<1|1]; del(rt<<1|1); } } int getnxt(int rt){ int lv=a[rt<<1],rv=a[rt<<1|1]; if(lv==0 && rv==0)return rt; else if(lv>=rv)return getnxt(rt<<1); else return getnxt(rt<<1|1); } int main(){ int t;cin>>t; for(int tt=1;tt<=t;tt++){ scanf("%d%d",&h,&g); ans.clear(); for(int i=1;i<=(1<<h+1);i++)a[i]=0; for(int i=1;i<(1<<h);i++)scanf("%d",&a[i]); for(int i=1;i<(1<<g);i++) while(1){ int nxt=getnxt(i);//找到下一个要删的点 if(nxt<=(1<<g)-1)break; del(i); ans.push_back(i); } ll sum=0; for(int i=1;i<(1<<g);i++)sum+=a[i]; cout<<sum<<'\n'; for(auto x:ans)cout<<x<<" "; puts(""); } }

 

posted on 2020-04-05 21:00  zsben  阅读(160)  评论(0编辑  收藏  举报

导航