蒟蒻指针线段树求调
  • 板块灌水区
  • 楼主stripe_python
  • 当前回复8
  • 已保存回复8
  • 发布时间2023/8/21 13:57
  • 上次更新2023/11/3 02:15:37
查看原帖
蒟蒻指针线段树求调
928879
stripe_python楼主2023/8/21 13:57

RT

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

template <class T>
class SegmentTree {
protected:
	struct node {
		T val, add;
		node *left, *right;
	
		node() : val(0), add(0), left(nullptr), right(nullptr) {}
		
		void pushup() {
			val = 0;
			if (left) val += left->val;
			if (right) val += right->val;
		}
		
		void pushdown(int ln, int rn) {
			if (!add) return;
			if (!left) left = new node;
			if (!right) right = new node;
			left->add += add, left->val += add * ln;
			right->add += add, right->val += add * rn;
			add = 0;
		}
	};
	
	int n;
	node* root;
	
	void clear(node* rt) {
		if (!rt) return;
		clear(rt->left), clear(rt->right);
		delete rt;
	}
	
	void build(const T* arr, int l, int r, node*& rt) {
		if (!rt) rt = new node;
		if (l == r) {
			rt->val = arr[l];
			return;
		}
		int mid = (l + r) >> 1;
		build(arr, l, mid, rt->left);
		build(arr, mid + 1, r, rt->right);
		rt->pushup();
	}
	
	void update(int x, int y, T c, int l, int r, node* rt) {
		if (!rt) return;
		if (x <= l && r <= y) {
			rt->add += c, rt->val += c * (r - l + 1);
			return;
		}
		int mid = (l + r) >> 1;
		rt->pushdown(mid - l + 1, r - mid);
		if (x <= mid) update(x, y, c, l, mid, rt->left);
		if (y > mid) update(x, y, c, mid + 1, r, rt->right);
		rt->pushup();
	}
	
	T query(int x, int y, int l, int r, node* rt) {
		if (!rt) return 0;
		if (x <= l && r <= y) return rt->val;
		int mid = (l + r) >> 1;
		rt->pushdown(mid - l + 1, r - mid);
		T res = 0;
		if (x <= mid) res += query(x, y, l, mid, rt->left);
		if (y > mid) res += query(x, y, mid + 1, r, rt->right);
		return res;
	}
	
public:
	SegmentTree() : n(0), root(nullptr) {}
	SegmentTree(const T* begin, const T* end) : n(0), root(nullptr) {
		build(begin, end);
	}
	~SegmentTree() {
		clear(root);
	}
	
	void build(const T* begin, const T* end) {
		n = end - begin;
		build(begin, 1, n, root);
	}
	
	void resize(int size) {n = size;}
	int size() {return n;}
	bool empty() {return n == 0;}
	
	void update(int l, int r, T c) {update(l, r, c, 1, n, root);}
	void update(int i, T c) {update(i, i, c, 1, n, root);}
	T query(int l, int r) {return query(l, r, 1, n, root);}
	T query(int i) {return query(i, i, 1, n, root);}
	void clear() {clear(root);}
};

SegmentTree<long long> tr;

int n, q, opt, x, y;
long long k, a[N];

int main() {
	scanf("%d %d", &n, &q);
	for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
	tr.build(a + 1, a + n + 1);
	while (q--) {
		scanf("%d %d %d", &opt, &x, &y);
		if (opt == 1) {
			scanf("%lld", &k);
			tr.update(x, y, k);
		} else if (opt == 2) {
			printf("%lld\n", tr.query(x, y));
		}
	}
	return 0;
}
2023/8/21 13:57
加载中...