【JZOJ4805】ksum
Description
给你一个
n
个数的数组,输出前
Solution
首先,最大肯定是全部加起来。
我们先把 [1,n] 扔进堆。
每次操作把最大的区间 [l,r] 取出来输出,扔出堆,然后把 [l,r−1] 和 [l+1,r] 扔进堆里。
但我们发现会有重复,于是只有当 r=n 时我们才把 [l+1,r] 扔进堆里。
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 100001
#define ll long long
using namespace std;
struct node{
friend bool operator< (node x,node y)
{
return x.v<y.v;
}
ll v;
int l,r;
};
priority_queue<node> q;
ll a[N],s[N];
int main()
{
freopen("ksum.in","r",stdin);
freopen("ksum.out","w",stdout);
int n,k;
cin>>n>>k;
fo(i,1,n)
{
scanf("%lld",&a[i]);
s[i]=s[i-1]+a[i];
}
node p;
p.v=s[n];
p.l=1;
p.r=n;
q.push(p);
fo(i,1,k)
{
printf("%lld ",q.top().v);
node p1=q.top(),p2=p1;
q.pop();
if(p1.r==n && p1.l<p1.r)
{
p1.v-=a[p1.l];
p1.l++;
q.push(p1);
}
if(p2.l<p2.r)
{
p2.v-=a[p2.r];
p2.r--;
q.push(p2);
}
}
}