Can you answer the question ? 线段树维护字段和

 要维护四个值,然后可以分析代码啦,洛谷时限230 ms 太坑了!!!

#pragma GCC optimize(2)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#define maxn 50010
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
using namespace std;
int n,m,x,y;

struct zmk{
    int lmax,rmax,dat,sum;
}T[maxn<<2];

inline int read(){
    int f=1,x=0; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
    return f*x;
}

inline void pushup(int o){
    T[o].sum=T[o<<1].sum+T[o<<1|1].sum;
    T[o].lmax=max(T[o<<1].lmax,T[o<<1].sum+T[o<<1|1].lmax);
    T[o].rmax=max(T[o<<1|1].rmax,T[o<<1|1].sum+T[o<<1].rmax);
    T[o].dat=max(max(T[o<<1].dat,T[o<<1|1].dat),T[o<<1].rmax+T[o<<1|1].lmax);
}

inline void build(int o,int l,int r){
    if(l==r){
        T[o].sum=T[o].lmax=T[o].rmax=T[o].dat=read();
        return;
    }
    int mid=(l+r)>>1;
    build(o<<1,l,mid);
    build(o<<1|1,mid+1,r);
    pushup(o);
}

inline zmk query(int o,int l,int r,int lt,int rt){
    if(lt<=l&&rt>=r) return T[o];
    int mid=(l+r)>>1;
    if(lt>mid) return query(rson,lt,rt);	
    if(rt<=mid) return query(lson,lt,rt);
    else{
        zmk a,b,ans;
        a=query(lson,lt,rt);b=query(rson,lt,rt); 
        ans.sum=a.sum+b.sum;
        ans.dat=max(max(a.dat,b.dat),a.rmax+b.lmax);
        ans.lmax=max(a.lmax,a.sum+b.lmax);
        ans.rmax=max(b.rmax,b.sum+a.rmax);	    
        return ans;
    }
}

int main(){
    //freopen("data.txt","r",stdin);
    //freopen("biaoda.txt","w",stdout);
    n=read();
    build(1,1,n);
    m=read();
    for(int i=1;i<=m;i++){
        int lt=read(),rt=read();
        printf("%d\n",query(1,1,n,lt,rt).dat);
    }
    return 0;
} 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#define SIZE 50010
#define lson p<<1,l,mid
#define rson p<<1|1,mid+1,r
using namespace std;
int n,m,ss,x,y;
struct SegmentTree{
    int sum,lmax,rmax,dat;
}tr[SIZE<<2];

inline int rin(){
    int f=1,x=0; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
    return f*x;
}
inline void Update(int p){
    tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum;
    tr[p].lmax=max(tr[p<<1].lmax,tr[p<<1].sum+tr[p<<1|1].lmax);
    tr[p].rmax=max(tr[p<<1|1].rmax,tr[p<<1|1].sum+tr[p<<1].rmax);
    tr[p].dat=max(max(tr[p<<1].dat,tr[p<<1|1].dat),tr[p<<1].rmax+tr[p<<1|1].lmax);
}
inline void Build(int p,int l,int r){
    if(l==r){tr[p].dat=tr[p].sum=tr[p].lmax=tr[p].rmax=rin(); return;}
    int mid=(l+r)>>1;
    Build(lson); Build(rson);
    Update(p);
}
inline void change(int p,int l,int r,int x,int y){
    if(l==r){tr[p].dat=tr[p].sum=tr[p].lmax=tr[p].rmax=y; return;}
    int mid=(l+r)>>1;
    if(x<=mid) change(lson,x,y);
    else change(rson,x,y);
    Update(p);
}
inline SegmentTree Query(int p,int l,int r,int ql,int qr){
    if(ql<=l&&qr>=r) return tr[p];
    int mid=(l+r)>>1;
    if(ql>mid) return Query(rson,ql,qr);
    if(qr<=mid) return Query(lson,ql,qr);
    else{
        SegmentTree ans,a,b;
        a=Query(lson,ql,qr); b=Query(rson,ql,qr);
        ans.sum=a.sum+b.sum;
        ans.dat=max(a.dat,a.rmax+b.lmax),ans.dat=max(ans.dat,b.dat);
        ans.lmax=max(a.lmax,a.sum+b.lmax);
        ans.rmax=max(b.rmax,b.sum+a.rmax);
        return ans;
    }
}

int main(){
    n=rin();
    Build(1,1,n);
    m=rin();
    for(int i=1;i<=m;i++){
        ss=rin(),x=rin(),y=rin();
        if(ss==1) printf("%d\n",Query(1,1,n,x,y).dat);
        if(ss==0) change(1,1,n,x,y);
    }

    return 0;
}

这个更多的是一个思路清楚,分情况讨论 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; 
const int maxn=10010;
int n,m,t;
struct zmk{
    int lmax,rmax,sum,res;
}a[40010];
zmk noww;
int b[maxn];
inline void pushup(int o){
    a[o].sum=a[o<<1].sum+a[o<<1|1].sum;
    a[o].lmax=max(a[o<<1].lmax,a[o<<1].sum+a[o<<1|1].lmax);
    a[o].rmax=max(a[o<<1|1].rmax,a[o<<1|1].sum+a[o<<1].rmax);
    a[o].res=max(max(a[o<<1].res,a[o<<1|1].res),a[o<<1].rmax+a[o<<1|1].lmax);
}
inline void Build(int p,int l,int r){
    if(l==r){a[p].res=a[p].sum=a[p].lmax=a[p].rmax=b[l]; return;}
    int mid=(l+r)>>1;
    Build(p<<1,l,mid); Build(p<<1|1,mid+1,r);
    pushup(p);
}
inline zmk query(int o,int l,int r,int ql,int qr){
    if(qr<ql) return noww;
    if(ql<=l&&qr>=r) return a[o];
    int mid=(l+r)/2;
    if(ql>mid) return query(o<<1|1,mid+1,r,ql,qr);
    else if(qr<=mid) return query(o<<1,l,mid,ql,qr);
    else{
        zmk sa,sb,ans;
        sa=query(o<<1,l,mid,ql,qr);
        sb=query(o<<1|1,mid+1,r,ql,qr);
        ans.sum=sa.sum+sb.sum;
        ans.lmax=max(sa.lmax,sa.sum+sb.lmax);
        ans.rmax=max(sb.rmax,sb.sum+sa.rmax);
        ans.res=max(max(sa.res,sb.res),sa.rmax+sb.lmax);
        return ans;
    }
}
int main(){
    scanf("%d",&t);
    while(t--){
        //memset(b,0,sizeof(0));
        //memset(a,0,sizeof(0));
        cin>>n;
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);
        Build(1,1,n);
        cin>>m;
        for(int i=1;i<=m;i++){
        	int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            if(x2>y1) cout<<max(query(1,1,n,x1,y1-1).rmax,0)+query(1,1,n,y1,x2).sum+max(query(1,1,n,x2+1,y2).lmax,0)<<endl;
            else{
            	int anss=query(1,1,n,x2,y1).res;
            	anss=max(anss,max(query(1,1,n,x1,x2-1).rmax,0)+max(query(1,1,n,y1+1,y2).lmax,0)+query(1,1,n,x2,y1).sum);
            	anss=max(anss,query(1,1,n,x1,x2-1).rmax+query(1,1,n,x2,y1).lmax);
            	anss=max(anss,query(1,1,n,x2,y1).rmax+query(1,1,n,y1+1,y2).lmax);
            	cout<<anss<<endl;
            }
        }
    }
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_42759194/article/details/81809044