又是一道线段树区间更新的题;
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
#define maxn 500005
using namespace std;
ll sum[maxn];
struct tree
{
int l,r;
int ml,mr;
int pre,suf;
tree *left,*right;
} tr[maxn*]; int trcount; void build(tree *root,int l,int r)
{
root->l=l;
root->r=r;
if(l==r)
{
root->ml=l;
root->mr=r;
root->pre=l;
root->suf=r;
return;
}
trcount++;
root->left=tr+trcount;
trcount++;
root->right=tr+trcount;
int mid=(l+r)/;
build(root->left,l,mid);
build(root->right,mid+,r); //update the pre
if((sum[root->left->pre]-sum[root->l-])>=(sum[root->right->pre]-sum[root->l-]))
root->pre=root->left->pre;
else root->pre=root->right->pre;
//update the suf
if((sum[root->r]-sum[root->left->suf-])>=(sum[root->r]-sum[root->right->suf-]))
root->suf=root->left->suf;
else root->suf=root->right->suf;
//update the max
if((sum[root->left->mr]-sum[root->left->ml-])>=(sum[root->right->mr]-sum[root->right->ml-]))
{
root->ml=root->left->ml;
root->mr=root->left->mr;
}
else
{
root->mr=root->right->mr;
root->ml=root->right->ml;
}
//update the max
if((sum[root->mr]-sum[root->ml-])<(sum[root->right->pre]-sum[root->left->suf-]))
{
root->mr=root->right->pre;
root->ml=root->left->suf;
}
else if((sum[root->mr]-sum[root->ml-])==(sum[root->right->pre]-sum[root->left->suf-]))
{
if(root->left->suf<root->ml||(root->left->suf==root->ml&&root->right->pre<root->mr))
{
root->mr=root->right->pre;
root->ml=root->left->suf;
}
}
} void query(tree *root,int ql,int qr,int &x,int &y,int &ansl,int &ansr)
{
if((ql<=root->l)&&(root->r<=qr))
{
x=root->ml;
y=root->mr;
ansl=root->pre;
ansr=root->suf;
return;
}
int mid=(root->r+root->l)>>;
if(qr<=mid)query(root->left,ql,qr,x,y,ansl,ansr);
else if(ql>=mid+)query(root->right,ql,qr,x,y,ansl,ansr);
else
{
int x1,x2,y1,y2,pre1,pre2,suf1,suf2; query(root->left,ql,mid,x1,y1,pre1,suf1);
query(root->right,mid+,qr,x2,y2,pre2,suf2); ansl=(sum[pre1]-sum[root->l-])>=(sum[pre2]-sum[root->l-])?pre1:pre2;
ansr=(sum[root->r]-sum[suf1-])>=(sum[root->r]-sum[suf2-])?suf1:suf2; if((sum[y1]-sum[x1-])>=(sum[y2]-sum[x2-]))
{
x= x1;
y= y1;
}
else
{
x= x2;
y= y2;
}
if((sum[pre2]-sum[suf1-])>(sum[y]-sum[x-]))
{
x= suf1;
y= pre2;
}
else if((sum[pre2]-sum[suf1-])==(sum[y]-sum[x-]))
{
if((suf1<x)||((suf1==x)&&(pre2<y)))
{
x = suf1;
y = pre2;
}
}
}
} int main()
{
int n,q,ca=;
while(scanf("%d%d",&n,&q)!=EOF)
{
ll x;
trcount=;
memset(sum,,sizeof sum);
for(int i=; i<=n; i++)
{
scanf("%lld",&x);
sum[i]=sum[i-]+x;
}
build(tr,,n);
int a,b,ans1,ans2,xx,yy;
printf("Case %d:\n",ca++);
while(q--)
{
scanf("%d%d",&a,&b);
query(tr,a,b,xx,yy,ans1,ans2);
printf("%d %d\n",xx,yy);
}
}
return ;
}