堆(STL优先队列)学习笔记
- 最大堆STL写法
- 创建的方法 priority_queue pd;
- 插入元素 的方式 pd.push();
- 提取队头 pd.front();
- 弹出队头 pd.pop();
要注意优先队列也是一种队列,就是说只能在队尾插入,并且只能弹出队头,所以要得到队列中第n小的数必须弹出前n-1的所有元素
2.最小堆STL写法
- 其他的跟最大堆一样,但是这里需要重载(或者使用迭代器),这里介绍一种简单的方式
struct cmp{
bool operator()(const int &a,const int &b){
return a>b;
}
}
priority_queue<int,vector<int>,cmp>;
在做题目的时候,经常发现,这个题目裸做会TLE
然后我发现一个小技巧
举个例子
题面
直接加只有50
我们考虑优化
先将两个序列排序,不难发现,对于每个a[i]都有a[i]+b[i]<=a[i]+b[i+1]所以仅当a[i[+b[i]被弹出时才加入a[i]+b[i+1]和a[i+1]+b[i],这种做法我当然不会啦,只是想到了
一共要取N个数,那我们依然先排序,来一点乱搞做法,我们在循环的时候
加一句话
for(int i=1;i<=n;i++)
for(int j=1;(i-1)*(j-1)<=n&&j<=n;j++)
pq.push(a[i]+b[j]);
你看第一眼肯定想说这种东西不是很明显是错的吗
我们在满足优先队列有大于N个元素的情况下,尽量进入最少的数
注意,i-1,j-1是精髓
请你仔细想想
假设此时要把 a[i]+b[j] 插入堆,且(i-1)*(j-1)>N,那么这个数一定不会是最后的答案,因为对于1<=s<i,1<=t<j,可组成的和已经超过N个,且都要比a[i]+b[j]小(因为a[i]>a[i-1],b[i]>b[i-1])