[NOI2010]超级钢琴 划分树+堆

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define N 510000
struct P{
   int x,y;
   P(int a=0,int b=0){x=a,y=b;}
   bool operator<(P a)const{
       return y<a.y;
    }
};
int val[N][23],num[N][23],ci[N];
int s[N];
int n,k,L,R;
void build(int h,int L,int R){
   if(L==R)return;
   int mid=(L+R)/2,left=L,right=mid+1,same=mid-L+1;
   for(int i=L;i<=R;i++)if(val[i][h]<s[mid])same--;
    for(int i=L;i<=R;i++){
        if(val[i][h]<s[mid])val[left++][h+1]=val[i][h];
        else if(val[i][h]==s[mid]&&same){
           val[left++][h+1]=val[i][h];
           --same;
        }else{
           val[right++][h+1]=val[i][h];

        }
          num[i][h]=num[L-1][h]+left-L;
    }
    build(h+1,L,mid);
    build(h+1,mid+1,R);
}
int kth(int h,int L,int R,int x,int y,int k){
   if(L==R)return val[L][h];
   int mid=(L+R)/2,left=num[y][h]-num[x-1][h];
   int pre=num[x-1][h]-num[L-1][h];
   if(left>=k)return kth(h+1,L,mid,L+pre,L+pre+left-1,k);
   else{
      k-=left;
      pre=x-L-pre;
      left=y-x+1-left;
      return kth(h+1,mid+1,R,mid+pre+1,mid+pre+left,k);
   }
}
int Kth(int x,int y,int k){
   return kth(1,1,n,x,y,k);
}
priority_queue<P> jj;
int l[N],r[N];
long long ans;
int main(){
    scanf("%d%d%d%d",&n,&k,&L,&R);
    for(int i=1;i<=n;i++){
       int a;
       scanf("%d",&a);
       s[i]=s[i-1]+a;
    }
    for(int i=1;i<=n;i++)val[i][1]=s[i];
    sort(s+1,s+n+1);
    build(1,1,n);
    for(int i=1;i<=n-L+1;i++){
        l[i]=i+L-1;
        r[i]=min(n,i+R-1);
        jj.push(P(i,Kth(l[i],r[i],r[i]-l[i]+1)-val[i-1][1]));
    }
    for(int i=1;i<=k;i++){
        P x=jj.top();
        jj.pop();
        ans+=x.y;
        if(r[x.x]-l[x.x]>ci[x.x]){jj.push(P(x.x,Kth(l[x.x],r[x.x],r[x.x]-l[x.x]-ci[x.x])-val[x.x-1][1]));
        ci[x.x]++;
        }
    }
    cout<<ans;
}

[NOI2010]超级钢琴 划分树+堆

时间: 2024-12-14 09:51:32

[NOI2010]超级钢琴 划分树+堆的相关文章

BZOJ 2006 NOI2010 超级钢琴 划分树+堆

题目大意:给定一个序列,找到k个长度在[l,r]之间的序列,使得和最大 暴力O(n^2logn).肯定过不去 看到这题的第一眼我OTZ了一下午...后来研究了非常久别人的题解才弄明确怎么回事...蒟蒻果然不能理解大神的思路啊0.0 首先维护前缀和,那么以第i个元素结尾的和最大的序列自然就是sum[i]-min{sum[j]}(i-r<=j<=i-l) 然后我们维护一个大根堆.每取走一个以i为结尾的元素,增加sum[i]-2thmin{sum[j]},再取走这个元素就增加sum[i]-3thmi

【BZOJ2006】[NOI2010]超级钢琴 ST表+堆

[BZOJ2006][NOI2010]超级钢琴 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负. 一个“超级和弦”由若干个编号连续的音符组成,包含的音符个数不少于L且不多于R.我们定义超级和弦的美妙度为其包含的所有音符的美妙度之和.两个超级和弦被认为是相同的,当且仅当这两个超级和弦所包含的音符集合是相同的. 小Z决定创作

[BZOJ2006][NOI2010]超级钢琴(ST表+堆)

2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 3679  Solved: 1828[Submit][Status][Discuss] Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负. 一个“超级 和弦”由若干个编号连续的音符组成,

[BZOJ2006] [NOI2010]超级钢琴 主席树+贪心+优先队列

2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 3591  Solved: 1780[Submit][Status][Discuss] Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负. 一个"超级 和弦"由若干个编号连续的

bzoj2006 noi2010 超级钢琴 主席树 + 优先队列

Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2435  Solved: 1195 Description 小 Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负. 一个“超级和弦”由若干个编号连续的音符组成,包含的音符个数不少于L且不多于R.我们定义超级和弦的美妙度为其包含的所有音符的美妙度之和.两

2006: [NOI2010]超级钢琴|ST表|堆

由于K很小,所以就直接取出最大的K个值加起来即可 考虑一个(i,l,r)表示以i开始以[l,r]中的某个位置结束的区间和的最大值,假设这个位置为p,然后把这些东西都存起来一起扔到堆中,每次取出区间和最大的一个元素,然后继续向堆中添加新的元素,直接对(i,l,p?1),(i,p+1,r)这两个组合再分别找出最大的区间和再扔到堆中,然后重复此过程直到找出前K大 (i,l,r)组合的最大区间和为max(sum[l],sum[l+1]...sum[r])?sum[i?1],找(i,l,r)组合的最大区间

Bzoj 2006: [NOI2010]超级钢琴 堆,ST表

2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2222  Solved: 1082[Submit][Status][Discuss] Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负. 一个“超级和弦”由若干个编号连续的音符组成,包含

BZOJ 2006: [NOI2010]超级钢琴( RMQ + 堆 )

取最大的K个, 用堆和RMQ来加速... ----------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; typedef long long ll; typedef pair<int, int> p

BZOJ 2006: [NOI2010]超级钢琴

2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2613  Solved: 1297[Submit][Status][Discuss] Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负. 一个“超级 和弦”由若干个编号连续的音符组成,