【ybtoj高效进阶 21255】【ybtoj高效进阶 21267】子段的和 / 降序排序(堆)

子段的和 / 降序排序

题目链接:ybtoj高效进阶 21255 / ybtoj高效进阶 21267

题目大意

给你一个由非负数组成的数组,问你其中前 w 大的子区间和。

思路

由于是非负数,不难想到用堆解决。

(对于每个右起点先左端点为 1 1 1 放入堆中,然后每次取出当前最大的区间,然后右移它的左端点)

代码

#include<queue>
#include<cstdio>
#define ll long long

using namespace std;

int n, w, a[100001];
int to[100001];
priority_queue <pair<ll, int>, vector<pair<ll, int> >, less<pair<ll, int> > > q;

int main() {
//	freopen("ksum.in", "r", stdin);
//  freopen("ksum.out", "w", stdout);
	
//	freopen("wsum.in", "r", stdin);
//	freopen("wsum.out", "w", stdout);
	
	scanf("%d %d", &n, &w);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]); to[i] = n;
	}
	
	ll now = 0;
	for (int i = n; i >= 1; i--) {
		now += 1ll * a[i];
		q.push(make_pair(now, i));
	}
	
	for (int i = 1; i < w; i++) {
		int now = q.top().second;
		ll val = q.top().first;
		printf("%lld ", val);
		q.pop();
		
		if (to[now] > now) {
			val -= a[to[now]];
			q.push(make_pair(val, now));
			to[now]--;
		}
	}
	printf("%lld", q.top().first);
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值