题解:
先维护个前缀和sum。然后以i为结束的串就可以有几个j作为开始节点,值sum[i]-sum[j-1]。
我们取最优的j,把sum-sum加到堆里面。
这样就可以O(1)取出最优串值,
取出后,对于这个i,就可以有一个第二优的j为开始的串,我们再把这个串值加入到堆中。
而这个j的优劣因为只跟sum有关,所以不妨写一个主席树寻找静态区间第K大,取得这个j。
这样我们只需要取j次,维护j次,就可以得到最终答案。
数据很良心啊,1A了。。数据范围有代码中注释
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 501000 // N的范围50W,|Ai|<= 1000
#define LOGN 20
#define ls son[x][0]
#define rs son[x][1]
#define sz size[x]
#define inf 0x3f3f3f3f
using namespace std;
int sum[N],crs[N],n,m,L,R,rank;
long long ans;
struct LSH
{
int x,id;
bool operator < (const LSH &a)const{return x<a.x;}
}lsh[N];
struct Heap
{
int val[N],id[N],cnt;
void pushup(int x){while((x>>1)&&val[x]>val[x>>1])swap(val[x],val[x>>1]),swap(id[x],id[x>>1]),x>>=1;}
void pushdown(int x)
{
int son;
while((x<<1)<=cnt)
{
son=((x<<1|1)<=cnt&&val[x<<1]<val[x<<1|1])?(x<<1|1):(x<<1);
if(val[x]<val[son])swap(val[x],val[son]),swap(id[x],id[son]),x=son;
else break;
}
}
void push(int w,int note)
{
++cnt;
val[cnt]=w,id[cnt]=note;
pushup(cnt);
}
int top(){return val[1];}
int pop()
{
int ret=id[1];
val[1]=val[cnt],id[1]=id[cnt];
cnt--;
pushdown(1);
return ret;
}
}Heap;
struct Functional_Segment_Tree
{
int son[N*LOGN][2],size[N*LOGN];
int cnt,pos[N];
void pushup(int x){sz=size[ls]+size[rs];}
int build(int last,int l,int r,int d)
{
int x=++cnt;
sz=size[last];
if(l==r){sz++;return x;}
int mid=l+r>>1;
if(d<=mid)ls=build(son[last][0],l,mid,d),rs=son[last][1];
else rs=build(son[last][1],mid+1,r,d),ls=son[last][0];
pushup(x);
return x;
}
int query(int last,int now,int l,int r,int k)
{
if(size[now]-size[last]<k)return inf;
if(l==r){return l;}
int temp=size[son[now][0]]-size[son[last][0]],mid=l+r>>1;
if(temp<k)return query(son[last][1],son[now][1],mid+1,r,k-temp);
else return query(son[last][0],son[now][0],l,mid,k);
}
void func()
{
for(int i=0;i<=n;i++)pos[i+1]=build(pos[i],1,rank,sum[i]);
}
}fst;
int state[N];
int main()
{
// freopen("test.in","r",stdin);
int i,j,k;
int a,b;
scanf("%d%d%d%d",&n,&m,&L,&R);
for(i=1;i<=n;i++)scanf("%d",&lsh[i+1].x),lsh[i+1].x+=lsh[i].x,lsh[i+1].id=i;
sort(lsh+1,lsh+n+2);
sum[lsh[1].id]=rank=1,crs[1]=lsh[1].x;
for(i=2;i<=n+1;i++)
{
if(lsh[i].x!=lsh[i-1].x)crs[++rank]=lsh[i].x;
sum[lsh[i].id]=rank;
}
fst.func();
for(i=1;i<=n;i++)
{
a=max(-1,i-R-1)+1;
b=max(-1,i-L)+1;
k=fst.query(fst.pos[a],fst.pos[b],1,rank,state[i]=1);
if(k<inf)Heap.push(crs[sum[i]]-crs[k],i);
}
while(m--)
{
if(!Heap.cnt)
{
puts("****");
return 0;
}
ans+=Heap.top();
j=Heap.pop();
a=max(-1,j-R-1)+1;
b=max(-1,j-L)+1;
k=fst.query(fst.pos[a],fst.pos[b],1,rank,++state[j]);
if(k<inf)Heap.push(crs[sum[j]]-crs[k],j);
}
cout<<ans<<endl;
return 0;
}