线段树60分求调,必关
查看原帖
线段树60分求调,必关
1007096
Handezheng楼主2024/10/10 16:06
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define F(i,l,r) for(int i = l;i <= r;i++)
const int N = 1e6 + 50,M = 1e3 + 50;
const int INF = 0x3f3f3f3f3f3f3f3f,INT = 0x7fffffff;
const int mod = 1e9 + 7;

int n,Q,a[N];
struct tree{
	int l,r;
	int bcm,add,max;
}tr[N<<3];
struct Tree{
	#define ls rt<<1
	#define rs rt<<1|1
	
	inline void pushup(int rt){
		tr[rt].max=max(tr[ls].max,tr[rs].max);
	}
	inline void pushdown(int rt){
		if(tr[rt].bcm==-INF && tr[rt].add==0) return ;
		int a=tr[rt].add,b=tr[rt].bcm;
		if(b!=-INF){
			tr[ls].max=tr[rs].max=b;
			tr[ls].bcm=tr[rs].bcm=b;
			tr[rt].bcm=-INF;
		}
		tr[ls].max+=a,tr[rs].max+=a;
		tr[ls].add+=a,tr[rs].add+=a;
		tr[rt].add=0;
	}
	inline void build(int rt,int l,int r){
		tr[rt].l=l,tr[rt].r=r,tr[rt].bcm=-INF;
		if(l==r){
			tr[rt].max=a[l];
			return ;
		}
		int mid=l+r>>1;
		build(ls,l,mid);
		build(rs,mid+1,r);
		pushup(rt);
	}
	inline void update(int rt,int l,int r,int k,int op){
		if(l<=tr[rt].l && tr[rt].r<=r){
			if(op==1){
				tr[rt].max=k;
				tr[rt].bcm=k;
				tr[rt].add=0;
			}else{
				tr[rt].add+=k;
				tr[rt].max+=k;
			}return ;
		}
		pushdown(rt);
		int mid=tr[rt].l+tr[rt].r>>1;
		if(l<=mid) update(ls,l,r,k,op);
		if(r> mid) update(rs,l,r,k,op);
		pushup(rt);
	}
	inline int query(int rt,int l,int r){
		if(l<=tr[rt].l && tr[rt].r<=r) return tr[rt].max;
		pushdown(rt);
		int ans=-INF,mid=tr[rt].l+tr[rt].r>>1;
		if(l<=mid) ans=max(ans,query(ls,l,r));
		if(r> mid) ans=max(ans,query(rs,l,r));
		pushup(rt);
		return ans; 
	}
}T;

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	
	cin>>n>>Q;
	F(i,1,n) cin>>a[i];
	T.build(1,1,n);
	F(cas,1,Q){
		int op,l,r,k;
		cin>>op>>l>>r;
		if(op!=3){
			cin>>k;
			T.update(1,l,r,k,op);
		}else cout<<T.query(1,l,r)<<'\n';
	}

	return 0;
}
2024/10/10 16:06
加载中...