数据结构中的堆

优先队列是队列数据结构实现,其中根据优先级处理对象,在优先队列中,添加的对象根据其优先级,默认情况下,优先级由对象的自然顺序决定的。队列构建时提供的比较器可以覆盖默认优先级。

优先队列就是一个堆,它可以维护一个集合的最大值(或最小值),可以在很优秀的时间复杂度(log级别)内进行查询,插入push和删除pop.

例题

问题描述

小雷拿到了一个数组,他计算了一下数组的和,感觉和也太大了,所以他准备对数组中的每个元素进行取余操作,让数组的和变得小一点。

具体来说,给定一个数组 a ,共有 q 次操作,每次操作给定一个值 x ,对数组的每个元素对 x 进行一次取模,输出每次操作后,数组所有元素的和。

输入格式

第一行有两个整数n,q ,代表数组 a 的元素个数和操作个数。

第二行输入 n 个元素,代表数组 a 。

第三行输入 q 个元素,代表 q 次操作。

输出格式

输出仅一行,包含 q 个由空格分开的整数,第 i 个整数代表第 qi​ 次操作后的结果。

样例输入

5 3
1 2 3 4 5
4 2 1

样例输出 

7 3 0

说明 

初始数组为 [1,2,3,4,5] ,和为 15 。

进行第一次 x 为 4 的取模操作后,数组变为 [1,2,3,0,1] ,和为 7 。

进行第二次 x 为 2 的取模操作后,数组变为 [1,0,1,0,1] ,和为 3 。

进行第三次 x 为 1 的取模操作后,数组变为 [0,0,0,0,0] ,和为 0。

构建数值从大到小的优先序列

每次比较对头和x的大小关系,如果队头大于x,把对头弹出来,将队头对x取模的值压入队列中。

代码

package dui;
import java.util.*;
public class chapter1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scan=new Scanner(System.in);
		int n=scan.nextInt();
		int q=scan.nextInt();
		long sum=0;
		PriorityQueue<Integer> queue=new PriorityQueue<>((o1,o2)->o2-o1);
		for(int i=0;i<n;i++) {
			int x=scan.nextInt();
			queue.add(x);
			sum+=x;
		}
		while(q-->0) {
			//q次操作
			int k=scan.nextInt();
			while(!queue.isEmpty()&&queue.peek()>=k) {
				//判断队列是否为空,以及对头中的元素大于我们当前要取余的值
				int x=queue.poll();//弹出(一直弹出比k大的数)
				sum-=x;
				queue.add(x%k);//对k取余后的值添加到队列中
				sum+=x%k;
			}
			System.out.print(sum+" ");//每次需要输出sum
		}
		
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值