线段树求调
查看原帖
线段树求调
642504
tuanzi_awa楼主2023/7/30 11:11

模板改自OI-WIKI的线段树模板

range_max区间最大

range_min区间最小

range_sum区间求和

range_set区间赋值

range_add区间加法

样例输出为9 6 9 15,错误

#include <bits/stdc++.h>
using namespace std;

template <typename T>
class SegTreeLazyRangeAddSet {
	private:
		vector<T> tree, lazy;
		vector<T> *arr;
		int n, root, n4, end;
		
		void maintain(int cl, int cr, int p) {
			int cm = cl + (cr - cl) / 2;
			if (cl != cr && lazy[p]) {
				lazy[p * 2] += lazy[p];
				lazy[p * 2 + 1] += lazy[p];
				tree[p * 2] += lazy[p] * (cm - cl + 1);
				tree[p * 2 + 1] += lazy[p] * (cr - cm);
				lazy[p] = 0;
			}
		}
		
		T range_sum(int l, int r, int cl, int cr, int p) {
			if (l <= cl && cr <= r) return tree[p];
			int m = cl + (cr - cl) / 2;
			T sum = 0;
			maintain(cl, cr, p);
			if (l <= m) sum += range_sum(l, r, cl, m, p * 2);
			if (r > m) sum += range_sum(l, r, m + 1, cr, p * 2 + 1);
			return sum;
		}
		
		T range_max(int l, int r, int cl, int cr, int p) {
			if (l <= cl && cr <= r) return tree[p];
			int m = cl + (cr - cl) / 2;
			T mAx = -2147483648;
			maintain(cl, cr, p);
			if (l <= m) mAx = max(mAx, range_max(l, r, cl, m, p * 2));
			if (r > m) mAx = max(mAx, range_max(l, r, m + 1, cr, p * 2 + 1));
			return mAx;
		}
	
		T range_min(int l, int r, int cl, int cr, int p) {
			if (l <= cl && cr <= r) return tree[p];
			int m = cl + (cr - cl) / 2;
			T mIn = 2147483647;
			maintain(cl, cr, p);
			if (l <= m) mIn = min(mIn, range_max(l, r, cl, m, p * 2));
			if (r > m) mIn = min(mIn, range_max(l, r, m + 1, cr, p * 2 + 1));
			return mIn;
		}
	
		void range_set(int l, int r, T val, int cl, int cr, int p) {
			if (l <= cl && cr <= r) {
				lazy[p] = val;
				tree[p] = (cr - cl + 1) * val;
				return;
			}
			int m = cl + (cr - cl) / 2;
			maintain(cl, cr, p);
			if (l <= m) range_set(l, r, val, cl, m, p * 2);
			if (r > m) range_set(l, r, val, m + 1, cr, p * 2 + 1);
			tree[p] = tree[p * 2] + tree[p * 2 + 1];
		}
		
		void range_add(int l, int r, T val, int cl, int cr, int p) {
			if (l <= cl && cr <= r) {
				lazy[p] += val;
				tree[p] += (cr - cl + 1) * val;
				return;
			}
			int m = cl + (cr - cl) / 2;
			maintain(cl, cr, p);
			if (l <= m) range_add(l, r, val, cl, m, p * 2);
			if (r > m) range_add(l, r, val, m + 1, cr, p * 2 + 1);
			tree[p] = tree[p * 2] + tree[p * 2 + 1];
		}
		
		void build(int s, int t, int p) {
			if (s == t) {
				tree[p] = (*arr)[s];
				return;
			}
			int m = s + (t - s) / 2;
			build(s, m, p * 2);
			build(m + 1, t, p * 2 + 1);
			tree[p] = tree[p * 2] + tree[p * 2 + 1];
		}
	
	public:
		explicit SegTreeLazyRangeAddSet<T>(vector<T> v) {
			n = v.size();
			n4 = n * 4;
			tree = vector<T>(n4, 0);
			lazy = vector<T>(n4, 0);
			arr = &v;
			end = n - 1;
			root = 1;
			build(0, end, 1);
			arr = nullptr;
		}
		
		void show(int p, int depth = 0) {
			if (p > n4 || tree[p] == 0) return;
			show(p * 2, depth + 1);
			for (int i = 0; i < depth; ++i) putchar('\t');
			printf("%d:%d\n", tree[p], lazy[p]);
			show(p * 2 + 1, depth + 1);
		}
		
		T range_sum(int l, int r) { return range_sum(l, r, 0, end, root); }
	
		T range_max(int l, int r) { return range_max(l, r, 0, end, root); }
	
		T range_min(int l, int r) { return range_min(l, r, 0, end ,root); }
	
	    void range_set(int l, int r, int val) { range_set(l, r, val, 0, end, root); }
		
		void range_add(int l, int r, int val) { range_add(l, r, val, 0, end, root); }
};
int n,m,x,x1;
char o;
vector<int>a(100005);
SegTreeLazyRangeAddSet<int>st(a);
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>x;
	    st.range_set(i,i,x);
	}
	for(int i=1;i<=m;i++){
		cin>>o>>x>>x1;
		if(o=='Q'){
			cout<<st.range_max(x,x1)<<endl;
		}
		if(o=='U'){
			if(st.range_sum(x,x)<x1){
				st.range_set(x,x,x1);
			}
		}
	}
}
2023/7/30 11:11
加载中...