#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+5, mod = 1e9+7;
int a[N], n, m;
int tr[N<<2], tag[N<<2], tagc[N<<2];
//struct node{
//	sum, tag1, tag2;
//} tr[N<<2]; 

void pushup(int k){
 	tr[k] = max(tr[k<<1], tr[k<<1|1]);
}

void build(int k, int l, int r){ // 当前结点k, 维护区间 [l, r] 
	tagc[k] = 1e18; 
	if(l == r) {
		tr[k] = a[r];
		return ;
	}
	int mid = l + r >> 1;
	build(k<<1, l, mid);  	 //k<<1 => k*2
	build(k<<1|1, mid+1, r);  //k<<1|1 => k*2+1
	pushup(k);
}

void upd(int k, int l, int r, int tag1, int tag2) { // 更新节点信息 
	if(tag1 != 1e18){
		tr[k] = tag1;
		tagc[k] = tag1;
		tag[k] = 0; //
	}
	else {
		tr[k] += tag2;
		if(tagc[k] != 1e18)
			tagc[k] += tag2;
		else 
			tag[k] += tag2;
	}
}

void pushdown(int k, int l, int r){ // 标记下放 

	int mid = r+l>>1;
	upd(k<<1, l, mid, tagc[k], tag[k]);
	upd(k<<1|1, mid+1, r, tagc[k], tag[k]);
	tagc[k] = 1e18;
	tag[k] = 0;
}

int query(int k, int l, int r, int x, int y){ 
	// k号结点,维护区间[l,r]。要查找的区间 [x, y]
	if(x <= l && r <= y){
		return tr[k];
	}
	int mid = l + r >> 1;
	pushdown(k, l, r);
	int ans = -1e18;
	if(x <= mid)  // 需要查询的区间有一部分在左孩子
		ans = max(ans, query(k<<1, l, mid, x, y));
	if(y > mid) // 需要查询的区间有一部分在右孩子
		ans = max(ans, query(k<<1|1, mid+1, r, x, y));
	return ans;
}



void modify(int k, int l, int r, int x, int y, int tag1, int tag2){ 
// k号结点,维护额区间[l,r]  要给区间 [x, y], +w 
	if(x <= l && r <= y){
//		tag[k] += w;
//		tr[k] += (r-l+1)*w;  // [l, r] + w
		upd(k, l, r, tag1, tag2); // 更新节点 
		return ;
	} 
	int mid = l + r >> 1;
	pushdown(k, l, r); // 向下传递 tag
	if(x <= mid) 
		modify(k<<1, l, mid, x, y, tag1, tag2);
	if(y > mid)
		modify(k<<1|1, mid+1, r, x, y, tag1, tag2);
	pushup(k);
}

signed main() {
	ios::sync_with_stdio(0); 
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	for(int i = 1; i <= n; i++)
		cin >> a[i];
	build(1, 1, n); 
	
//	modify(1, 1, n, 1, 2, 6, 0);
//	modify(1, 1, n, 1, 2, 1e18, 2);
	
//	cout << query(1, 1, n, 1, 4);
	
	while(m--){
		int op, x, y, w;
		cin >> op;
		if(op == 1){
			cin >> x >> y >> w;
			modify(1, 1, n, x, y, w, 0);
		} else if(op == 2) {
			cin >> x >> y >> w;
			modify(1, 1, n, x, y, 1e18, w);
		} else{
			cin >> x >> y;
			cout << query(1, 1, n, x, y) << "\n";
		}
	}
	return 0;
}


2 条评论

  • 1