LA 3938 动态的最大连续和(线段树)

第一次学习线段树

#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;
}
发布了75 篇原创文章 · 获赞 77 · 访问量 4017

猜你喜欢

转载自blog.csdn.net/weixin_43568895/article/details/104103737
LA