蒟蒻刚自学线段树求助:样例过了但20pts
查看原帖
蒟蒻刚自学线段树求助:样例过了但20pts
253608
Tx_Lcy楼主2021/12/21 21:52
#include<bits/stdc++.h>
using namespace std;
#define ls x<<1
#define rs x<<1|1
#define mid (l+r)/2
int const N=1e6+10;
int f[N<<2],a[N],la1[N],la[N];
void build(int x,int l,int r){
	if (l==r){f[x]=a[l];return;}
	build(ls,l,mid);
	build(rs,mid+1,r);
	f[x]=max(f[ls],f[rs]);
	//cout<<x<<' '<<l<<' '<<r<<' '<<f[x]<<'\n';
}
void pushdown(int x){
	if (la1[x]>=0){
		f[ls]=f[rs]=la1[x];
		la1[ls]=la1[rs]=la1[x];
		la1[x]=0;
		la[ls]=la[rs]=0; 
	}else{
   	    la[ls]+=la[x];
	    la[rs]+=la[x];
	    la[x]=0;
	    f[ls]+=la[x];
	    f[rs]+=la[x];
	}
}
void update(int x,int l,int r,int ll,int rr,int k){
	if (ll<=l && r<=rr){
		la[x]=0;
        la1[x]=k;
        f[x]=k;
        return;
	}
	if (r<ll || l>rr) return;
	pushdown(x);
	if (mid<rr) update(rs,mid+1,r,ll,rr,k);
	if (mid>=ll) update(ls,l,mid,ll,rr,k);
    f[x]=max(f[ls],f[rs]);
}
void add(int x,int l,int r,int ll,int rr,int k){
    if (ll<=l && r<=rr){
		la[x]+=k;
        f[x]+=k;
        return;
	}
	if (r<ll || l>rr) return;
	pushdown(x);
	if (mid<rr) add(rs,mid+1,r,ll,rr,k);
	if (mid>=ll) add(ls,l,mid,ll,rr,k);
    f[x]=max(f[ls],f[rs]);
}
int query(int x,int l,int r,int ll,int rr){
	if (ll<=l && r<=rr){
        return f[x];
	}
	if (r<ll || l>rr) return 0;
	pushdown(x);
	int sum=0;
	if (mid<rr) sum=max(sum,query(rs,mid+1,r,ll,rr));
	if (mid>=ll) sum=max(sum,query(ls,l,mid,ll,rr));
    f[x]=max(f[ls],f[rs]);
    return sum;
}
int main(){
	memset(la1,-0x3f,sizeof(la1));
	ios::sync_with_stdio(false);
	int n,q;cin>>n>>q;
	for (int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
	while (q--){
    	int op;cin>>op;
    	if (op==1){
    		int l,r,x;cin>>l>>r>>x;
    		update(1,1,n,l,r,x);
		}
		if (op==2){
			int l,r,x;cin>>l>>r>>x;
			add(1,1,n,l,r,x);
		}
		if (op==3){
			int l,r;cin>>l>>r;
			cout<<query(1,1,n,l,r)<<'\n';
		}
	}
	return 0;
}
2021/12/21 21:52
加载中...