40,求调
查看原帖
40,求调
819682
Exile_Code楼主2024/1/1 23:56
#define  _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <list>
#include <string>
#include <cmath>
#include <bitset>
#include <stack>
#include <unordered_set>
#include <math.h>
#include <functional>
#include<unordered_map>

#define ull             unsigned long long 
#define ll              long long
#define pii             pair<ll,ll>
#define ft              first
#define sd              second
#define cy              cout<<"YES"<<endl
#define cn              cout<<"NO"<<endl
#define forn(i,n)       for(ll (i)=0;(i)<(n);(i)++)   
#define forne(i,n)      for(ll (i)=1;(i)<=(n);(i)++)
#define rforn(i,n)      for(ll (i)=(n-1);i>=0;i--)
#define rforne(i,n)     for(ll (i)=n;i>=1;i--)
#define vv              vector
#define inf             1e9
const int N = 4e5 + 100;
const int mod = 1e9 + 7;
ll T;

class Segment_tree {
	/*
	叶子节点储存元素本身,非叶子节点存储统计值,用来维护区间和,区间最值,区间GCD
	父节点的编号是p,左孩子的编号是2p,右孩子的编号是2p+1
	*/
	struct node {
		ll l, r, add,mx,upd;
	};
	vv<node>tr;
	vv<ll>w;
#define lc p<<1
#define rc (p<<1)|1
//p<<2一定是一个偶数,偶数的末位是0,所以按位或1,相当于+1
#define LEN(x) (tr[(x)].r - tr[(x)].l + 1)	//区间长度包括端点
#define MID(x) (tr[(x)].l + tr[(x)].r) >> 1	//中间点
#define trpl tr[p].l
#define trpr tr[p].r
#define trps tr[p].sum
#define trpd tr[p].add
public:
	void init(int n) {
		tr = vv<node>(4 * n + 3);
		w = vv<ll>(n + 1);
		forne(i, n)
			cin >> w[i];
		build(1, 1, n);
	}
	void pushup(int p) {
		//trps = tr[lc].sum + tr[rc].sum;
		tr[p].mx = max(tr[lc].mx, tr[rc].mx);
	}
	void build(int p, int l, int r) {
		tr[p] = { l,r,0,w[l],0 };
		if (l == r)		return;
		int m = MID(p);
		build(lc, l, m); build(rc, m + 1, r);
		pushup(p);
	}
	ll query(int p, int l, int r) {
		ll mx = -1e9-100;	
		if (l <= trpl && trpr <= r)
			return tr[p].mx;
		int m = MID(p);	pushdown(p);
		if (l <= m)	mx=max(mx,query(lc, l, r));
		if (r > m)	mx=max(mx,query(rc, l, r));
		return mx;
	}
	void pushdown(int p) {
		if (tr[p].upd) {
			tr[p].mx = tr[p].upd;
			tr[lc].upd = tr[p].upd;
			tr[rc].upd = tr[p].upd;
			tr[lc].add =0;
			tr[rc].add =0;
			tr[p].upd = 0;
		}
		if (tr[p].add) {
			tr[lc].mx += tr[p].add;
			tr[rc].mx += tr[p].add;
			tr[lc].add += trpd;
			tr[rc].add += trpd;
			tr[p].add = 0;
		}
	}
	//区间查询,拆分拼凑
	//如果查询区间完全覆盖掉当前的节点区间,就立刻返回当前的区间值 On
	void update(int p, int l, int r, int k) {
		if (l <= trpl && trpr <= r) {
			if (tr[p].upd != 0)
				tr[p].upd += k;
			else
				trpd += k;
			tr[p].mx += k;
			return;
		}
		int m = MID(p);
		pushdown(p);
		if (l <= m)	update(lc, l, r, k);
		if (r > m)	update(rc, l, r, k);
		pushup(p);
	}
	void update_all(int p, int l, int r, int x) {
		if (l <= trpl && trpr <= r) {
			tr[p].upd = x;
			tr[p].add = 0;
			tr[p].mx = x;
			return;
		}
		int m = MID(p);
		pushdown(p);
		if (l <= m)	update_all(lc, l, r, x);
		if (r > m)	update_all(rc, l, r, x);
		pushup(p);
	}
};
void solve() {

	//1 1 4 5 1 4
	//6 6 4 5 1 4
	//6 6 6 7 1 4
	//

	int n, q;
	cin >> n >> q;
	Segment_tree fuction;
	fuction.init(n);
	while (q--) {
		int ch; cin >> ch;
		if (ch == 1) {
			int l, r, x; cin >> l >> r >> x;
			fuction.update_all(1, l, r, x);
		}
		else if(ch==2) {
			int l, r, x; cin >> l >> r >> x;
			fuction.update(1,l, r, x);
		}
		else {
			int l, r; cin >> l >> r;
			cout << fuction.query(1, l, r) << endl;
		}

	}



}
int main() {

	T = 1;
	//cin >> T;
	while (T--)
		solve();
}
2024/1/1 23:56
加载中...