长代码找手误真的难= =。很容易脑补成对的,然后就混过去了。其实不应该贪快嫌麻烦,一定要想清楚。
线段树维护:区间左坐标,区间右坐标,区间和,最大连续和,最大连续和左坐标,最大连续和右坐标,最大前缀和,最大前缀和右坐标,最大后缀和,最大后缀和左坐标。
如果区间和相等,都是在保证左坐标最小的情况下,右坐标最小。
可以证明当区间和相等时,选择右边>左+右>选择左边。
以前一直都没用结构体,而且递归时询问区间都不变的(就是只会水题),所以搞了好久。
代码
#include<bits/stdc++.h>
#define maxn 500010
using namespace std;
typedef long long ll;
ll n,m;
ll a[maxn];
struct Node
{
ll l,r,sub,subl,subr,pre,prer,suf,sufl,sum;
};
Node tree[maxn<<2];
void BUILD(ll l,ll r,ll now)
{
tree[now].l=l;
tree[now].r=r;
if(l==r)
{
tree[now].sum=tree[now].sub=tree[now].pre=tree[now].suf=a[l];
tree[now].subl=tree[now].subr=tree[now].prer=tree[now].sufl=l;
return;
}
ll m=l+(r-l)/2;
BUILD(l,m,now<<1);
BUILD(m+1,r,now<<1|1);
tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
tree[now].sub=tree[now<<1|1].sub;
tree[now].subl=tree[now<<1|1].subl;
tree[now].subr=tree[now<<1|1].subr;
if(tree[now<<1].suf+tree[now<<1|1].pre>=tree[now].sub)
{
tree[now].sub=tree[now<<1].suf+tree[now<<1|1].pre;
tree[now].subl=tree[now<<1].sufl;
tree[now].subr=tree[now<<1|1].prer;
}
if(tree[now<<1].sub>=tree[now].sub)
{
tree[now].sub=tree[now<<1].sub;
tree[now].subl=tree[now<<1].subl;
tree[now].subr=tree[now<<1].subr;
}
if(tree[now<<1].pre>=tree[now<<1].sum+tree[now<<1|1].pre)
{
tree[now].pre=tree[now<<1].pre;
tree[now].prer=tree[now<<1].prer;
}
else
{
tree[now].pre=tree[now<<1].sum+tree[now<<1|1].pre;
tree[now].prer=tree[now<<1|1].prer;
}
if(tree[now<<1|1].suf>tree[now<<1|1].sum+tree[now<<1].suf)
{
tree[now].suf=tree[now<<1|1].suf;
tree[now].sufl=tree[now<<1|1].sufl;
}
else
{
tree[now].suf=tree[now<<1|1].sum+tree[now<<1].suf;
tree[now].sufl=tree[now<<1].sufl;
}
}
Node Q(ll l,ll r,ll now)
{
if(l==tree[now].l&&r==tree[now].r) return tree[now];
ll m=tree[now].l+(tree[now].r-tree[now].l)/2;
if(r<=m) return Q(l,r,now<<1);
if(l>m) return Q(l,r,now<<1|1);
Node ans;
Node ansl=Q(l,m,now<<1);
Node ansr=Q(m+1,r,now<<1|1);
ans.l=l;
ans.r=r;
ans.sum=ansl.sum+ansr.sum;
ans.sub=ansr.sub;
ans.subl=ansr.subl;
ans.subr=ansr.subr;
if(ansl.suf+ansr.pre>=ans.sub)
{
ans.sub=ansl.suf+ansr.pre;
ans.subl=ansl.sufl;
ans.subr=ansr.prer;
}
if(ansl.sub>=ans.sub)
{
ans.sub=ansl.sub;
ans.subl=ansl.subl;
ans.subr=ansl.subr;
}
if(ansl.pre>=ansl.sum+ansr.pre)
{
ans.pre=ansl.pre;
ans.prer=ansl.prer;
}
else
{
ans.pre=ansl.sum+ansr.pre;
ans.prer=ansr.prer;
}
if(ansr.suf>ansr.sum+ansl.suf)
{
ans.suf=ansr.suf;
ans.sufl=ansr.sufl;
}
else
{
ans.suf=ansr.sum+ansl.suf;
ans.sufl=ansl.sufl;
}
return ans;
}
ll kase;
int main()
{
while(scanf("%lld %lld",&n,&m)==2)
{
for(ll i=1;i<=n;i++)
scanf("%lld",&a[i]);
printf("Case %lld:\n",++kase);
BUILD(1,n,1);
ll l,r;
while(m--)
{
scanf("%lld %lld",&l,&r);
Node ans=Q(l,r,1);
printf("%lld %lld\n",ans.subl,ans.subr);
}
}
return 0;
}