|洛谷|NOIP2015|堆|P2672 推销员

https://www.luogu.org/problem/show?pid=2672

开两个大根堆,一个维护小于当前走的最远距离的住户,一个维护大于当前走的最远距离的住户

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define ms(i,j) memset(i,j, sizeof i);
using namespace std;
int n; 
struct node
{
	int si;
	int ai;
}user[100005];
struct data
{
	int vi;
	int no;
	data(int v, int n) : vi(v), no(n){} 
};
struct cmp
{
	bool operator ()(data a, data b)
	{
		return a.vi<b.vi;
	}
};
priority_queue<data, vector<data>, cmp> p1,p2;
int now = 0;
int main()
{
	scanf("%d", &n);
	for (int i=1;i<=n;i++)
	{
		scanf("%d", &user[i].si);
	}
	for (int i=1;i<=n;i++)
	{
		scanf("%d", &user[i].ai);
		if (i<now) p1.push(data(user[i].ai, i));
		else p2.push(data(2*(user[i].si-user[now].si)+user[i].ai, i));
	}
	int tot = 0;
	for (int i=1;i<=n;i++)
	{
		data a=data(0,0),b=data(0,0);
		if (!p1.empty()) {a = p1.top();}
		if (!p2.empty()) {b = p2.top();} 
		if (a.vi>b.vi)
		{
			tot+=a.vi;
			printf("%d\n", tot);
			p1.pop();
		} else 
		{
			tot+=b.vi;
			printf("%d\n", tot);
			while (!p2.empty()) p2.pop();
			for (int i=now+1;i<b.no;i++)
			{
				p1.push(data(user[i].ai,i));
			}
			for (int i=b.no+1;i<=n;i++)
			{
				p2.push(data(2*(user[i].si-user[b.no].si)+user[i].ai, i));
			}
			now = b.no;
		}
	}
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值