[codeforces 1330E] Drazil Likes Heap 堆元素删除+堆深度+贪心

Codeforces Round #631 (Div. 2) - Thanks, Denis aramis Shitov!   比赛人数10889

[codeforces 1330E]   Drazil Likes Heap   堆元素删除+堆深度+贪心

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址https://codeforces.com/contest/1330/problem/E

Problem Lang Verdict Time Memory
E - Drazil Likes Heap GNU C++11 Accepted 545 ms 12200 KB

题意理解:

以如下数据为例

3 2
7 6 3 5 4 2 1

10
3 2 3 1

说明:
3 2 3 1分别对应,最新堆的元素位置

上述数据生成过程,如下图

上述数据为什么不能依次删去最新堆中的最大值:7,6,5,4,若按这种方式删除,对应的数据生成过程,如下图

很明显,这种删除方式,高度未变,故错误。

思路同https://www.cnblogs.com/huangdalaofighting/p/12637116.html

1.每次删除一个节点,由它大儿子(数值大的儿子)和大孙子(数值大的孙子)组成的链的深度−1。
2.一个节点不可删,当且仅当它大儿子(数值大的儿子)和大孙子(数值大的孙子)等组成的链的深度等于g。
3.一个节点不可删,那么它的大儿子(数值大的儿子)也不可删。由它大儿子(数值大的儿子)和大孙子(数值大的孙子)组成的链都不能删。
于是得到贪心算法,如果根节点能删则删,否则把左右儿子当作根分别进行删除操作。
这样能够保证随后得到的堆的元素和是最小的。

上述数据,贪心算法如下

AC代码如下。

#include <stdio.h>
#define maxn 2100000
#define LL long long
#define lson(x) (x<<1)
#define rson(x) ((x<<1)|1)
int a[maxn],b[maxn/2],g,h,cnt,n,m;
LL sum;
void del(int x){//删除x位置处元素
	if(a[lson(x)]==0&&a[rson(x)]==0)a[x]=0;
	else{
		if(a[lson(x)]>a[rson(x)])a[x]=a[lson(x)],del(lson(x));
		else a[x]=a[rson(x)],del(rson(x));
	}
}
int getdepth(int x,int dep){//求x这条链上对应的深度.dep表示当前x位置所在深度
	if(a[lson(x)]>a[rson(x)])return getdepth(lson(x),dep+1);
	else if(a[lson(x)]<a[rson(x)])return getdepth(rson(x),dep+1);//a[lson(x)]<a[rson(x)]
	else return dep;//a[lson(x)]==a[rson(x)]==0;
}
void dfs(int x,int dep){//dep表示当前x位置所在深度
	if(a[x]==0)return;
	while(getdepth(x,dep)>g)sum-=a[x],b[++cnt]=x,del(x);
	dfs(lson(x),dep+1);//左子树
	dfs(rson(x),dep+1);//右子树
}
int main(){
	int i,t;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&h,&g);
		n=(1<<h)-1,m=(1<<g)-1;
		for(i=1;i<=m;i++)b[i]=0;//初始化别忘了
		for(i=n+1;i<=2*n+1;i++)a[i]=0;//最后一个元素位置n,左孩子2*n,右孩子2*n+1
		sum=0,cnt=0;//初始化别忘了
		for(i=1;i<=n;i++)scanf("%d",&a[i]),sum+=a[i];
		dfs(1,1);
		printf("%lld\n",sum);
		for(i=1;i<n-m;i++)printf("%d ",b[i]);
		printf("%d\n",b[n-m]);
	}
	return 0;
}

编写过程,收获颇丰,全是自己编写调试出来的。

弄明白了(1<<3)=8,(3<<1)=6.

树上递归的编写有些感觉了。

明白了,在多重测试数据下,变量的初始化太重要了。

发布了660 篇原创文章 · 获赞 562 · 访问量 48万+

猜你喜欢

转载自blog.csdn.net/mrcrack/article/details/105341752