16.10.7 A:4815. 【NOIP2016提高A组五校联考4】ksum
2016-10-12 20:37
330 查看
这道题目仔细想想就可以发现是一个堆,我们先做1~n的前缀和,然后我们把(1,n)放入堆,[a+1,b]和[a,b-1]才有可能成为下次取出的对
象,那么我就将[a+1,b]和[a,b-1]加进堆,这样重复 k 次即可,另外,如果每次都[a+1,b]和[a,b-1]加入堆,会得到重复的答案,那么,我们可以固定左端点。
反正c++优先队列爱怎么浪怎么堆怎么浪,就酱紫。
#include<cstdio> #include<queue> #define F(i,x,y) for(ll i=x;i<=y;i++) #define d(i,x,y) for(ll i=x;i>=y;i--) using namespace std; typedef long long ll; const ll maxn = 100000 + 200; ll a[maxn]; ll sum[maxn]; ll n,k; struct node { ll l,r; friend bool operator<(node x,node y) { return (sum[x.r] - sum[x.l-1]) < (sum[y.r] - sum[y.l-1]); } }x; priority_queue<node> q; inline ll read() { char ch = getchar(); ll data = 0; while(ch<'0' || ch>'9') ch = getchar(); while(ch>='0' && ch<='9') { data = data * 10 + ch - '0'; ch = getchar(); } return data; } int main() { freopen("ksum.in","r",stdin); //freopen("ksum.out","w",stdout); n = read(),k = read(); x.l = 1; x.r = n; sum[0] = 0; F(i,1,n) a[i] = read(),sum[i] = sum[i-1] + a[i]; q.push(x); d(i,k,1) { x = q.top(); q.pop(); printf("%lld ",sum[x.r] - sum[x.l-1]); if(x.r==n) { x.l++; q.push(x); x.l--; } x.r--; q.push(x); } printf("\n"); return 0; }
相关文章推荐
- JZOJ 4815. 【NOIP2016提高A组五校联考4】ksum
- [JZOJ 4815]【NOIP2016提高A组五校联考4】ksum
- JZOJ 4815 【NOIP2016提高A组五校联考4】ksum
- 【JZOJ4815】【NOIP2016提高A组五校联考4】ksum
- 【NOIP2016提高A组五校联考4】ksum
- ksum 【NOIP2016提高A组五校联考4】
- 【NOIP2016提高A组五校联考4】ksum
- 【NOIP2016提高A组五校联考4】ksum
- 【jzoj 4814】【NOIP2016提高A组五校联考2】tree
- JZOJ 4806 【NOIP2016提高A组五校联考3】打工
- 【NOIP2016提高A组五校联考2】tree
- 【NOIP2016提高A组五校联考4】label
- 【JZOJ4816】【NOIP2016提高A组五校联考4】label
- 【NOIP2016提高A组五校联考4】label
- 【JZOJ 4817】【NOIP2016提高组 五校联考4】square
- 【JZOJ 4809】【NOIP2016提高组 五校联考1】挖金矿
- 【NOIP2016提高A组五校联考4】square
- 【NOIP2016提高A组五校联考4】square
- 【JZOJ 4816】【NOIP2016提高组 五校联考4】label
- 【NOIP2016提高A组五校联考2】string