第一次学习线段树
#include<bits/stdc++.h>
#define lson l,m,i<<1
#define rson m+1,r,i<<1|1
typedef long long ll;
using namespace std;
const ll inf=1223372036854775807;
struct node{
ll v,l,r;
node(){}
node(ll a,ll b,ll c){
v=a,l=b,r=c;
}
bool operator < (const node b)const{
if(v!=b.v) return v<b.v;
if(l!=b.l) return l>b.l;
return r>b.r;
}
};
node query_pre(int qL,int qR,int l,int r,int i);
node query_suf(int qL,int qR,int l,int r,int i);
const int n=500005+50;
ll aa[n];
ll psum[n],ok;
node sub[4*n],pre[4*n],suf[4*n];
void push_pre(int i,int l,int r){
int mid=(l+r)>>1;
node r1(psum[mid]-psum[l-1]+pre[i<<1|1].v,l,pre[i<<1|1].r);
pre[i]=max(r1,pre[i<<1]);
}
void push_suf(int i,int l,int r){
int mid=(l+r)>>1;
node r1(psum[r]-psum[mid]+suf[i<<1].v,suf[i<<1].l,r);
suf[i]=max(r1,suf[i<<1|1]);
}
void pushup_ans(int i,int l,int r){
node r1(suf[i<<1].v+pre[i<<1|1].v,suf[i<<1].l,pre[i<<1|1].r);
r1=max(r1,sub[i<<1]);
sub[i]=max(r1,sub[i<<1|1]);
}
void build(int l,int r,int i){
if(l==r){
sub[i].l=pre[i].l=suf[i].l=l;
sub[i].r=pre[i].r=suf[i].r=r;
sub[i].v=pre[i].v=suf[i].v=aa[++ok];
return ;
}
int mid=(l+r)>>1;
build(l,mid,i<<1);
build(mid+1,r,i<<1|1);
push_pre(i,l,r);
push_suf(i,l,r);
pushup_ans(i,l,r);
}
node query_pre(int qL,int qR,int l,int r,int i)
{
if (qL <= l && r <= qR)
return pre[i];
int m = (l + r) >> 1;
node ret1(-inf,l,m),ret2(-inf,m+1,r);
if (qR <= m) return query_pre(qL , qR , lson);
if (qL > m) return query_pre(qL , qR , rson);
ret1 = query_pre(qL , qR , lson),ret2 = query_pre(qL , qR , rson);
int LL=max(qL,l),RR=min(qR,r);
node r1(psum[m]-psum[LL-1]+ret2.v,LL,ret2.r);
return max(ret1,r1);
}
node query_suf(int ql,int qr,int l,int r,int i){
if(ql<=l && r<=r) return suf[i];
int m=(l+r)>>1;
node ret1(-inf,l,m),ret2(-inf,m+1,r);
if(qr<=m) return query_suf(ql,qr,lson);
if(ql>m) return query_suf(ql,qr,rson);
ret1=query_suf(ql,qr,lson), ret2=query_suf(ql,qr,rson);
int ll=max(ql,l),rr=min(qr,r);
node r1(psum[rr]-psum[m]+ret1.v,ret1.l,rr);
return max(r1,ret2);
}
node query_max(int ql,int qr,int l,int r,int i){
if(ql<=l && r<=qr) return sub[i];
int m=(l+r)>>1;
node ret1(-inf,l,m),ret2(-inf,m+1,r);
if(qr<=m) return query_max(ql,qr,lson);
if(ql>m) return query_max(ql,qr,rson);
ret1=query_max(ql,qr,lson),ret2=query_max(ql,qr,rson);
node p1=query_pre(ql,qr,rson);
node s1=query_suf(ql,qr,lson);
node ret(p1.v+s1.v,s1.l,p1.r);
return max(ret,max(ret1,ret2));
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out1.txt","w",stdout);
int cnt=1;
ll n ,a,b,i,m;
while(scanf("%lld%lld", &n,&m)!=EOF)
{
for( i = 1; i <= n; i++)
{
scanf("%lld",&aa[i]);
psum[i]=aa[i]+psum[i-1];
}
// for( i = 1; i <= n; i++)
// update(1,1,n,i,i,psum[i]);
ok=0;
build(1,n,1);
int l,r;
printf("Case %d:\n",cnt++);
for (int i=1; i<=m; i++)
{
scanf("%d%d",&l,&r);
node ans=query_max(l,r,1,n,1);
printf("%lld %lld\n",ans.l,ans.r);
}
}
return 0;
}