堆和优先队列的练习

模版:

luogu 3378 【模板】堆

手写堆版本

#include<bits/stdc++.h>
using namespace std;
int cnt,heap[1100000];
int op,x,n;
void heap_add(int x){
	cnt++;
	heap[cnt]=x;
	int now=cnt;
	while(now>1&&heap[now]<heap[now/2])swap(heap[now],heap[now/2]),now>>=1;
}
void heap_delete(){
	int x,y;
	heap[1]=heap[cnt];
	cnt--;
	x=1;
	for(;;){
		y=x;
		if(x*2<=cnt&&heap[x*2]<heap[y])y=x*2;
		if(x*2+1<=cnt&&heap[x*2+1]<heap[y])y=x*2+1;
		if(x==y)break;
		swap(heap[x],heap[y]);
		x=y; 
	}
}
int read(){
	int x=0,flag=1;
	char ch=getchar();
	while(!(ch>='0'&&ch<='9')){
		if(ch=='-')flag=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*flag;
}
int main(){
	n=read();
	while(n--){
		op=read();
		if(op==1){
			x=read();
			heap_add(x);
		}
		if(op==2)printf("%d\n",heap[1]);
		if(op==3)heap_delete();
	}
	return 0;
}

stl版本

#include<bits/stdc++.h>
using namespace std;
int n,op,x;
priority_queue<int,vector<int>,greater<int> >heap;
int read(){
	int x=0,flag=1;
	char ch=getchar();
	while(!(ch>='0'&&ch<='9')){
		if(ch=='-')flag=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	return flag==1?x:-x;
}
int main(){
	n=read();
	while(n--){
		op=read();
		if(op==1){
			x=read();
			heap.push(x);
		}
		if(op==2)printf("%d\n",heap.top());
		if(op==3)heap.pop();
	}
	return 0;
}

luogu 1631 序列合并

地址:https://www.luogu.com.cn/problem/P1631
重载运算

#include<bits/stdc++.h>
using namespace std;
#define N 11000
struct data{
	int x,id,cnt;
}d;
priority_queue<data,vector<data>,less<data> >heap;
bool operator <(data a,data b){return a.x>b.x;}//注意不要忘记加bool 
int n,m,a[N],b[N],c[N];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i]>>b[i]>>c[i];
		d.x=a[i]+b[i]+c[i];
		d.id=i;
		d.cnt=1;
		heap.push(d);
	}
	for(int i=1;i<=m;i++){
		data x=heap.top();
		heap.pop();
		cout<<x.x<<" ";
		x.cnt++;
		x.x=x.cnt*x.cnt*a[x.id]+x.cnt*b[x.id]+c[x.id];
		heap.push(x);
	}
	return 0;
} 

luogu 1168 中位数

地址:https://www.luogu.com.cn/problem/P1168

#include<bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,less<int> >heapmax;
priority_queue<int,vector<int>,greater<int> >heapmin;
int n,x;
int main(){
	scanf("%d",&n);
	scanf("%d",&x);
	printf("%d\n",x);
	heapmax.push(x);
	for(int i=2;i<=n;i++){
		scanf("%d",&x);
		if(x<=heapmax.top())heapmax.push(x);
		else heapmin.push(x);
		while(heapmax.size()-1>heapmin.size()){
			x=heapmax.top();
			heapmax.pop();
			heapmin.push(x);
		}
		while(heapmin.size()>heapmax.size()){
			x=heapmin.top();
			heapmin.pop();
			heapmax.push(x);
		}
		if(i%2==1)printf("%d\n",heapmax.top());
	}
	return 0;
}

luogu 3419 [POI2005]SAM-Toy Cars

地址:https://www.luogu.com.cn/problem/P3419

#include<bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,less<int> >heap;
int n,k,p,flag[510000],next[510000],cnt,last[510000],ans,a[510000],x;
int main(){
	scanf("%d%d%d",&n,&k,&p);
	for(int i=1;i<=p;i++)scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)last[i]=p+1;
	for(int i=p;i>0;i--){
		next[i]=last[a[i]];
		last[a[i]]=i;
	}
	for(int i=1;i<=p;i++){
		x=a[i];
		if(flag[x]==1){
			heap.push(next[i]);
			continue;
		}
		ans++; 
		flag[x]=1;
		if(cnt<k){
			cnt++;
			heap.push(next[i]);
		}else{
			x=a[heap.top()];
			flag[x]=0;
			heap.pop();
			heap.push(next[i]);
		}
	}
	cout<<ans<<endl;
	return 0;
}

luogu 1801 黑匣子

地址:https://www.luogu.com.cn/problem/P1801

#include<bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,less<int> >heap_max;
priority_queue<int,vector<int>,greater<int> >heap_min;
int n,m,x,cnt;
int a[210000],b[210000];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1;i<=m;i++){
		scanf("%d",&x);
		b[x]++;
	}
	for(int i=1;i<=n;i++){
		if(heap_max.size()==0||a[i]<=heap_max.top())heap_max.push(a[i]);
		else heap_min.push(a[i]);
		while(b[i]){
			b[i]--;
			cnt++;
			while(heap_max.size()>cnt){
				x=heap_max.top();
				heap_max.pop();
				heap_min.push(x);
			}
			while(heap_max.size()<cnt){
				x=heap_min.top();
				heap_min.pop();
				heap_max.push(x);
			}
			printf("%d\n",heap_max.top());
		}
	}
	return 0;
}

luogu 1717 钓鱼

地址:https://www.luogu.com.cn/problem/P1717

#include<bits/stdc++.h>
using namespace std;
struct data{
	int x,id;
};
priority_queue<data,vector<data>,less<data> >heap;
bool operator <(data x,data y){
	return x.x<y.x;
}
int n,h,f[30],d[30],t[30],ans;
int main(){
	cin>>n;
	cin>>h;
	h*=12;
	for(int i=1;i<=n;i++)cin>>f[i];
	for(int i=1;i<=n;i++)cin>>d[i];
	for(int i=1;i<n;i++)cin>>t[i];
	for(int i=1;i<=n;i++){
		int now=h;
		for(int j=1;j<i;j++)now-=t[j];
		if(now<=0)break;
		while(heap.size())heap.pop();
		int sum=0;
		for(int j=1;j<=i;j++){
			data a;
			a.x=f[j];
			a.id=j;
			heap.push(a);
		}
		for(int j=1;j<=now;j++){
			data a;
			a=heap.top();
			heap.pop();
			sum+=a.x;
			a.x-=d[a.id];
			if(a.x<0)a.x=0;
			heap.push(a);
		}
		ans=max(ans,sum);
	}
	cout<<ans<<endl;
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值