需要注意的是 此题为动态查询,因为有多个询问,且范围给定
输出的答案 应保证x小,在x小的情况下y小,这只要在判断时调整判断顺序即可,
详见 紫书 p201 讲解很清晰,
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <set>
#include <queue>
using namespace std;
typedef long long ll;
const int INF=1e9+10;
const double EPS = 1e-10;
const ll mod=1e9+7;
typedef pair<int,int> P;
const int N=5000001;
int n,m;
struct Node{
ll suf,sub,pre,sum;
int l,r,prer,sufl;
}node[4*N];
void pushup(Node &rt,Node a,Node b){
ll mx;
mx=a.sub;
rt.sub=mx;
rt.l=a.l;
rt.r=a.r;
if(mx<a.suf+b.pre){
mx=1LL*a.suf+b.pre;
rt.sub=mx;
rt.l=a.sufl;
rt.r=b.prer;
}
if(mx<b.sub){
mx=b.sub;
rt.sub=mx;
rt.l=b.l;
rt.r=b.r;
}
mx=a.pre;
rt.pre=mx;
rt.prer=a.prer;
if(mx<a.sum+b.pre){
rt.pre=1LL*a.sum+b.pre;
rt.prer=b.prer;
}
mx=1LL*b.sum+a.suf;
rt.suf=mx;
rt.sufl=a.sufl;
if(mx<b.suf){
rt.suf=b.suf;
rt.sufl=b.sufl;
}
rt.sum=1LL*a.sum+b.sum;
}
void build(int l,int r,int rt){
if(l==r){
int x;
scanf("%d",&x);
node[rt].sum=node[rt].pre=node[rt].suf=node[rt].sub=1LL*x;
node[rt].l=node[rt].r=node[rt].prer=node[rt].sufl=l;
return;
}
int mid=(l+r)/2;
build(l,mid,rt*2);
build(mid+1,r,rt*2+1);
pushup(node[rt],node[rt*2],node[rt*2+1]);
}
Node query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return node[rt];
}
Node tmp,a,b;
int mid=(l+r)/2;
if(L<=mid){
a=query(L,R,l,mid,rt*2);
}
if(R>mid){
b=query(L,R,mid+1,r,rt*2+1);
}
if(L<=mid&&R>mid){
pushup(tmp,a,b);
return tmp;
}
else if(L<=mid){
return a;
}
else{
return b;
}
}
int main(){
//freopen("out.txt","w",stdout);
//ios_base::sync_with_stdio(0);
int case1=1;
while(scanf("%d %d",&n,&m)!=EOF){
build(1,n,1);
printf("Case %d:\n",case1++);
while(m--){
int l,r;
scanf("%d %d",&l,&r);
Node tmp=query(l,r,1,n,1);
printf("%d %d\n",tmp.l,tmp.r );
}
}
return 0;
}