[NOI2010]超级钢琴 - 主席树 - 堆

题目大意:问长度在[L,R]的前k大子区间的和。5e5。
题解:对每个右端点用主席树维护其第k大即可,然后光荣MLE。

#include<bits/stdc++.h>
#define gc getchar()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define db double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define INF 2000000000
#define N 500010
#define S(rt) (((rt)==NULL)?0:(rt)->s)
#define CH(rt,g) (((rt)==NULL)?NULL:(rt)->ch[g])
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
	int x=0,s=1,ch;while(((ch=gc)<'0'||ch>'9')&&ch!='-');
	if(ch^'-') x=ch^'0';else s=-1;
	while((ch=gc)>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^'0');
	return s*x;
}
struct segment{
	int s;segment *ch[2];
}*T[N];priority_queue<pii> q;int a[N],s[N],st[N],ed[N],cnt[N];
int build(segment* &x,segment *y,int l,int r,int p)
{
	x=new segment,x->s=S(y)+1;
	x->ch[0]=CH(y,0),x->ch[1]=CH(y,1);
	int mid=(l+r)>>1;if(l==r) return 0;
	if(p<=mid) build(x->ch[0],CH(y,0),l,mid,p);
	if(mid<p) build(x->ch[1],CH(y,1),mid+1,r,p);
	return 0;
}
int query(segment *x,segment *y,int l,int r,int k)
{
	if(S(x)-S(y)<k) return INF;int mid=(l+r)>>1,v;if(l==r) return l;
	if(k<=(v=S(CH(x,0))-S(CH(y,0)))) return query(CH(x,0),CH(y,0),l,mid,k);
	return query(CH(x,1),CH(y,1),mid+1,r,k-v);
}
inline int query(int s,int t,int c,int mx) { if(s>t) return INF;return query(T[t],s?T[s-1]:NULL,1,mx,c); }
int main()
{
//	freopen("data.in","r",stdin),freopen("std.out","w",stdout);
	int n=inn(),k=inn(),L=inn(),R=inn(),bas=1,mx=0;lint Ans=0ll;
	rep(i,1,n) a[i]=inn(),s[i]=s[i-1]+a[i],bas=max(bas,-s[i]+1),mx=max(mx,s[i]);
	mx+=bas;rep(i,0,n) s[i]+=bas,build(T[i],i?T[i-1]:NULL,1,mx,s[i]);
	rep(i,1,n) st[i]=max(i-R,0),ed[i]=i-L,cnt[i]=1,q.push(mp(s[i]-query(st[i],ed[i],1,mx),i));
	for(int x;k;k--) x=q.top().sec,Ans+=q.top().fir,q.pop(),q.push(mp(s[x]-query(st[x],ed[x],++cnt[x],mx),x));
	return !printf("%lld\n",Ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息学奥赛是一项重要的竞赛活动,旨在培养学生的计算机科学和信息技术能力。省选是指在全省范围内举办的预赛,参赛选手需要通过省选才能晋级到更高层次的比赛。在省选中发挥出色的选手将有机会代表本省参加全国信息学奥林匹克竞赛(NOI)。 而noi_pdf-2020.12.29.rar 是一个压缩文件的命名,其中包含了一份关于NOI的PDF文档。这个文件可能包含了有关NOI的相关资料,例如竞赛规则、题目类型、考试要求等等。通过研究这个文件,选手可以更好地准备信息学奥赛,提高竞赛成绩。 对于想要参加信息学奥赛的同学们来说,可以利用这份PDF文档来深入了解NOI的要求和考试内容。首先,可以仔细阅读竞赛规则,了解比赛的时间、地点、参赛资格等重要信息。其次,可以通过研究题目类型和考试要求,明确自己需要学习和复习的内容,制定合理的备考计划。此外,可以通过查阅往年的竞赛题目和解答,进行练习和模拟考试,提高解题能力和应变能力。 综上所述,信息学奥赛省选和noi_pdf-2020.12.29.rar对于想要参加信息学奥赛的同学们来说都有重要的意义。省选是选拔出优秀选手的一个重要阶段,而noi_pdf-2020.12.29.rar则提供了有关NOI的重要资料,帮助选手更好地准备竞赛。希望通过努力学习和准备,同学们可以在比赛中取得优异成绩,提升自己的计算机科学和信息技术能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值