下面这个代码有没有人帮忙大致看一看:
#include<cstdio>
#include<algorithm>
#include<set>
#include<queue>
#define inf 8333583335000000000ll
using namespace std;
int n,lcnt;
long long m,p,q;
int a[100005],lsum[100005];
long long sum[100005],rmax[100005],lmin[100005],ls[100005];
long long ans1,ans2,ans;
set<int>unu;
inline long long Min(long long x,long long y){return x<y?x:y;}
inline long long Max(long long x,long long y){return x>y?x:y;}
inline int lowbit(int k){return k&-k;}
struct ta{
long long t[100005];
void add(int k,long long x){for(;k<=lcnt;k+=lowbit(k))t[k]+=x;}
inline long long query(int k){long long ans=0;for(;k;k-=lowbit(k))ans+=t[k];return ans;}
}tsum,tnum;
struct ta2{
int t[100005];
void build(){for(int i=1;i<=lcnt;i++)t[i]=n+1;}
void add(int k,int x){for(;k<=lcnt;k+=lowbit(k))t[k]=Min(t[k],x);}
inline int query(int k){int ans=n+1;for(;k;k-=lowbit(k))ans=Min(ans,t[k]);return ans;}
}tmin;
struct subs{
int l,r;long long w;
bool operator >(const subs k)const{
if(w!=k.w)return w>k.w;
else if(r!=k.r)return r>k.r;
else return l>k.l;
}
bool operator <(const subs k)const{
if(w!=k.w)return w<k.w;
else if(r!=k.r)return r<k.r;
else return l<k.l;
}
bool operator ==(const subs k)const{return (k.l==l)&&(k.r==r)&&(k.w==w);}
bool operator !=(const subs k)const{return (k.l!=l)||(k.r!=r)||(k.w!=w);}
};
struct heap{
subs h[100005];
int top;
void pushdown(int k){
while((k<<1)<=top){
int v=k<<1;
if(v+1<=top)if(h[v|1]>h[v])v++;
if(h[v]>h[k])swap(h[v],h[k]);
else break;
k=v;
}
}
void pushup(int k){
while(k>1){
int v=k>>1;
if(h[v]<h[k])swap(h[v],h[k]);
else break;
k=v;
}
}
void push(subs k){
h[++top]=k;
pushup(top);
}
void pop(){
h[1]=h[top--];
pushdown(1);
}
}subsq;
void del(int k);
#define lson index<<1
#define rson index<<1|1
#define mid ((l+r)>>1)
struct sg1{
bool b[400005];
void cover(int L,int R,int l,int r,int index){
if(L>R)return;
if(b[index])return;
if(l==r){del(l);b[index]=true;return;}
if(L<=mid)cover(L,R,l,mid,lson);
if(R>mid)cover(L,R,mid+1,r,rson);
b[index]=b[lson]&&b[rson];
}
}s1;
struct t{
long long max[100005][17],min[100005][17];
int lo[100005];
void build(int l,int r,int index){
lo[1]=0;
for(int i=2;i<=n;i++)if((1<<(lo[i-1]+1))==i)lo[i]=lo[i-1]+1;
else lo[i]=lo[i-1];
for(int i=0;i<=n;i++)max[i][0]=min[i][0]=sum[i];
for(int i=1;i<=lo[n];i++)
for(int j=0;j+(1<<i)-1<=n;j++)max[j][i]=Max(max[j][i-1],max[j+(1<<(i-1))][i-1]),min[j][i]=Min(min[j][i-1],min[j+(1<<(i-1))][i-1]);
}
long long query(int l,int r){
int tmp=lo[r-l+1];
return Max(max[l][tmp],max[r-(1<<tmp)+1][tmp])-Min(min[l][tmp],min[r-(1<<tmp)+1][tmp]);
}
}s2;
#undef lson
#undef rson
struct node3{
int l,r,s;
};
struct sg3{
node3 t[4000005];
int root[100005],cnt;
void ins(int &rt,int l,int r,int k){
if(rt==0)rt=++cnt;
t[rt].s++;
if(l==r)return;
if(k<=mid)ins(t[rt].l,l,mid,k);
else ins(t[rt].r,mid+1,r,k);
}
void build(){for(int i=0;i<=n;i++)ins(root[lsum[i]],0,n,i);}
inline int qsum(int rt,int l,int r,int k){
if(rt==0)return 0;
if(r==k)return t[rt].s;
if(k<=mid)return qsum(t[rt].l,l,mid,k);
else return t[t[rt].l].s+qsum(t[rt].r,mid+1,r,k);
}
inline int query(int rt,int l,int r,int k){
if(l==r)return r;
if(k<=t[t[rt].l].s)return query(t[rt].l,l,mid,k);
else return query(t[rt].r,mid+1,r,k-t[t[rt].l].s);
}
}s3;
struct sg4{
node3 t[4000005];
int cnt,root[100005];
void ins(int &rt,int Rt,int l,int r,int k){
rt=++cnt;
if(l==r)return;
if(k<=mid){
t[rt].r=t[Rt].r;
ins(t[rt].l,t[Rt].l,l,mid,k);
}else{
t[rt].l=t[Rt].l;
ins(t[rt].r,t[Rt].r,mid+1,r,k);
}
}
void build(){ins(root[0],0,1,lcnt,lsum[0]);for(int i=1;i<=n;i++)ins(root[i],root[i-1],1,lcnt,lsum[i]);}
inline int query(int rt,int l,int r,int k){
if((k>r)||(rt==0))return 0;
if(l==r)return l;
if(k>mid)return query(t[rt].r,mid+1,r,k);
else{
int tmp=query(t[rt].l,l,mid,k);
if(tmp)return tmp;
else return query(t[rt].r,mid+1,r,k);
}
}
}s4;
struct splaynode{
int l,r,size,fa;
subs s;
long long sum;
};
struct Splay{
splaynode t[100005];
int root,top,cnt,stack[100005];
inline int newnode(){return stack[top--];}
void pushup(int rt){
t[rt].size=t[t[rt].l].size+t[t[rt].r].size+1;
t[rt].sum=t[t[rt].l].sum+t[t[rt].r].sum+t[rt].s.w;
}
void rorate(int k,int i){
int tmp=t[k].fa;
t[k].fa=t[tmp].fa;
if(t[t[tmp].fa].l==tmp)t[t[tmp].fa].l=k;
else t[t[tmp].fa].r=k;
t[tmp].fa=k;
if(i==0){
if(t[k].l>0)t[t[k].l].fa=tmp;
t[tmp].r=t[k].l;
t[k].l=tmp;
}else{
if(t[k].r>0)t[t[k].r].fa=tmp;
t[tmp].l=t[k].r;
t[k].r=tmp;
}
pushup(tmp);pushup(k);
}
void splay(int k,int g){
while(t[k].fa!=g){
int tmp=t[k].fa;
if(t[tmp].fa==g)if(t[tmp].r==k)rorate(k,0);
else rorate(k,1);
else{
int Tmp=t[tmp].fa;
if(t[Tmp].l==tmp){
if(t[tmp].l==k)rorate(tmp,1);
else rorate(k,0);
rorate(k,1);
}else{
if(t[tmp].r==k)rorate(tmp,0);
else rorate(k,1);
rorate(k,0);
}
}
}
if(g==0)root=k;
}
void build(int l,int r,int &rt){
rt=++cnt;
t[rt].s=(subs){mid+1,mid,0};
if(mid>l){
build(l,mid-1,t[rt].l);
t[t[rt].l].fa=rt;
}
if(r>mid){
build(mid+1,r,t[rt].r);
t[t[rt].r].fa=rt;
}
pushup(rt);
}
inline long long query(int k){
if(k>t[root].size)return -inf;
if(k==t[root].size)return t[root].sum;
int p=root;
while(t[t[p].r].size!=k){
if(k<t[t[p].r].size)p=t[p].r;
else k-=t[t[p].r].size+1,p=t[p].l;
}
splay(p,0);
return t[t[p].r].sum;
}
void ins(subs k){
if(root==0){
root=newnode();
t[root].l=t[root].r=t[root].fa=0;t[root].s=k;pushup(root);
return;
}
int p=root,v;
while(true){
if(k<t[p].s)
if(t[p].l)p=t[p].l;
else{t[p].l=v=newnode();break;}
else
if(t[p].r)p=t[p].r;
else{t[p].r=v=newnode();break;}
}
t[v].fa=p;t[v].l=t[v].r=0;t[v].s=k;pushup(v);splay(v,0);
}
void del(subs k){
if(t[root].size==1){root=0;return;}
int p=root;
while(t[p].s!=k){
if(k<t[p].s)p=t[p].l;
else p=t[p].r;
}
splay(p,0);
int tmp=t[p].l;
if(tmp==0){
t[t[p].r].fa=0;
root=t[p].r;
stack[++top]=p;
return;
}
while(t[tmp].r)tmp=t[tmp].r;
splay(tmp,root);
t[tmp].fa=0;root=tmp;
if(t[p].r)t[t[p].r].fa=tmp,t[tmp].r=t[p].r;
pushup(tmp);stack[++top]=p;
}
}s;
inline long long read(){
long long ret=0,p=1;char c=getchar();
while((c<'0')||(c>'9')){if(c=='-')p=-1;c=getchar();}
while((c>='0')&&(c<='9'))ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
return ret*p;
}
inline int find(long long k){
int l=0,r=lcnt+1;
while(r-l>1){
if(ls[mid]>k)r=mid;
else l=mid;
}
return l;
}
inline long long checknum(long long std){
long long ans=0;
for(int i=0;i<=n;i++){
ans+=tnum.query(find(sum[i]-std));
tnum.add(lsum[i],1);
}
for(int i=0;i<=n;i++)tnum.add(lsum[i],-1);
return ans;
}
void del(int k){
set<int>::iterator p=unu.find(k),st=unu.begin(),ed=unu.end();
ed--;
if(p!=st){
set<int>::iterator pre=p;pre--;
s.del((subs){(*pre)+1,k-1,s2.query((*pre),k-1)});
}
if(p!=ed){
set<int>::iterator nex=p;nex++;
s.del((subs){k+1,(*nex)-1,s2.query(k,(*nex)-1)});
}
if((p!=st)&&(p!=ed)){
set<int>::iterator pre=p,nex=p;pre--;nex++;
s.ins((subs){(*pre)+1,(*nex)-1,s2.query((*pre),(*nex)-1)});
}
unu.erase(k);
}
inline subs Next(subs now){
int l=now.l,r=now.r,L,R=r;
int tmp=s3.qsum(s3.root[lsum[l]],0,n,l);
if(tmp==1){
int S=s4.query(s4.root[r-1],1,lcnt,lsum[l]+1);
if(S==0)return (subs){0,R,-inf};
int Sum=s3.qsum(s3.root[S],0,n,r-1);
L=s3.query(s3.root[S],0,n,Sum);
}else L=s3.query(s3.root[lsum[l]],0,n,tmp-1);
return (subs){L,R,sum[R]-sum[L]};
}
inline long long checksum(long long std,long long rest){
long long ans=0;tmin.build();
for(int i=0;i<=n;i++){
int t=find(sum[i]-std);
rest-=tnum.query(t);
ans+=tnum.query(t)*sum[i];
ans+=tsum.query(t);
s1.cover(tmin.query(t)+1,i,1,n,1);
tnum.add(lsum[i],1);
tsum.add(lsum[i],-sum[i]);
tmin.add(lsum[i],i);
}
for(int i=0;i<=n;i++)tnum.add(lsum[i],-1);
std--;
ans+=rest*std;
tnum.add(lsum[0],1);
for(int i=1;i<=n;i++){
int Tmp=find(sum[i]-std);
if(ls[Tmp]!=sum[i]-std){
Tmp++;tnum.add(lsum[i],1);
int p=s4.query(s4.root[i-1],1,lcnt,Tmp);
if(p==0)continue;
int L=s3.query(s3.root[p],0,n,s3.qsum(s3.root[p],0,n,i-1));
subsq.push((subs){L,i,sum[i]-sum[L]});
}else{
int tmp=tnum.query(Tmp)-tnum.query(Tmp-1);
tnum.add(lsum[i],1);
if(tmp==0){
Tmp++;
int p=s4.query(s4.root[i-1],1,lcnt,Tmp);
if(p==0)continue;
int L=s3.query(s3.root[p],0,n,s3.qsum(s3.root[p],0,n,i-1));
subsq.push((subs){L,i,sum[i]-sum[L]});
}else if(tmp<=rest){
int L=s3.query(s3.root[Tmp],0,n,1);
s1.cover(L+1,i,1,n,1);rest-=tmp;
Tmp++;
int p=s4.query(s4.root[i-1],1,lcnt,Tmp);
if(p==0)continue;
L=s3.query(s3.root[p],0,n,s3.qsum(s3.root[p],0,n,i-1));
subsq.push((subs){L,i,sum[i]-sum[L]});
}else{
int L;
if(rest){
L=s3.query(s3.root[Tmp],0,n,tmp-rest+1);
s1.cover(L+1,i,1,n,1);
}
L=s3.query(s3.root[Tmp],0,n,tmp-rest);
subsq.push((subs){L,i,sum[i]-sum[L]});rest=0;
}
}
}
return ans;
}
void upans2(){
if(unu.empty()){ans2=-inf;return;}
ans2=s.query(q-1);
if(ans2==-inf)return;
set<int>::iterator p=unu.begin();
ans2-=lmin[(*p)-1];
p=unu.end();p--;
ans2+=rmax[(*p)];
}
void work(){
for(int i=1;i<=n;i++)unu.insert(i);
long long l=ls[1]-ls[lcnt]-5,r=ls[lcnt]-ls[1]+5;
while(r-l>1){
if(checknum(mid)>=p)l=mid;
else r=mid;
}
ans1=checksum(r,p);
upans2();
if(ans2>-inf)ans=ans1+ans2;
else ans=-inf;
}
void pre(){
n=read();m=read();
for(int i=1;i<=n;i++){a[i]=read();ls[i]=sum[i]=sum[i-1]+a[i];}
ls[n+1]=0;
sort(ls+1,ls+2+n);
ls[0]=-inf;
for(int i=1;i<=n+1;i++)if(ls[i]!=ls[i-1])ls[++lcnt]=ls[i];
for(int i=0;i<=n;i++)lsum[i]=find(sum[i]);
lmin[0]=sum[0];
for(int i=1;i<=n;i++)lmin[i]=Min(lmin[i-1],sum[i]);
rmax[n]=sum[n];
for(int i=n-1;i>=0;i--)rmax[i]=Max(rmax[i+1],sum[i]);
s2.build(1,n-1,1);s3.build();s4.build();s.build(1,n-1,s.root);
if(m>n)p=m-n,q=n;
else p=0,q=m;
work();
}
void doit(){
q--;p++;
for(;q;q--,p++){
subs tmp=subsq.h[1],Tmp=Next(tmp);
if(Tmp.w>-inf)subsq.h[1]=Next(tmp),subsq.pushdown(1);
else subsq.pop();
s1.cover(tmp.l+1,tmp.r,1,n,1);
ans1+=tmp.w;upans2();
if(ans2>-inf)ans=Max(ans,ans1+ans2);
}
ans1+=subsq.h[1].w;
s1.cover(subsq.h[1].l+1,subsq.h[1].r,1,n,1);
if(s1.b[1])ans=ans1;
printf("%I64d",ans);
}
int main(){
pre();
doit();
}