数据结构 - 线段树

数据结构 - 线段树

模板1 题目链接:https://www.luogu.org/problem/P3372

区间修改、区间查询 代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 100010;

int n, m;
ll num[N];

struct Segment_tree {
	ll tree[N << 2];
	ll lazy[N << 2];
	
	#define lson pos << 1
	#define rson pos << 1 | 1
	
	void pushup(int pos) {
		tree[pos] = tree[lson] + tree[rson];
	}
	
	void pushdown(int pos, int l, int r) {
		if (lazy[pos]) {
			int mid = (l + r) >> 1;
			lazy[lson] += lazy[pos];
			lazy[rson] += lazy[pos];
			tree[lson] += 1ll * (mid - l + 1) * lazy[pos];
			tree[rson] += 1ll * (r - mid) * lazy[pos];
			lazy[pos] = 0;
		}
	}
	
	void build(int pos, int l, int r) {
		if (l == r) {
			tree[pos] = num[l];
			return ;
		}
		int mid = (l + r) >> 1;
		build(lson, l, mid);
		build(rson, mid + 1, r);
		pushup(pos);
	}
	
	void update(int pos, int l, int r, int x, int y, ll v) {
		if (x <= l && r <= y) {
			tree[pos] += 1ll * (r - l + 1) * v;
			lazy[pos] += v;
			return ;
		}
		int mid = (l + r) >> 1;
		pushdown(pos, l, r);
		if (x <= mid) {
			update(lson, l, mid, x, y, v);
		}
		if (y > mid) {
			update(rson, mid + 1, r, x, y, v);
		}
		pushup(pos);
	}
	
	ll query(int pos, int l, int r, int x, int y) {
		if (x <= l && r <= y) {
			return tree[pos];
		}
		int mid = (l + r) >> 1;
		pushdown(pos, l, r);
		ll ret = 0;
		if (x <= mid) {
			ret += query(lson, l, mid, x, y);
		}
		if (y > mid) {
			ret += query(rson, mid + 1, r, x, y);
		}
		return ret;
	}
	#undef lson
	#undef rson
} sgt;

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i ++ ) {
		scanf("%lld", &num[i]);
	}
	sgt.build(1, 1, n);
	for (int i = 1; i <= m; i ++ ) {
		int opt, x, y;
		ll k;
		scanf("%d", &opt);
		if (opt == 1) {
			scanf("%d%d%lld", &x, &y, &k);
			sgt.update(1, 1, n, x, y, k);
		}
		else {
			scanf("%d%d", &x, &y);
			ll ans = sgt.query(1, 1, n, x, y);
			printf("%lld\n", ans);
		}	
	}
	return 0;
}

双修改(区间乘、区间加)

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

int n, m, mod;

int a[N];

struct Segment_tree {
	
	#define lson pos << 1
	#define rson pos << 1 | 1

	struct Tree {
		int mul, add, num; 
		Tree() {
			mul = add = num = 0;
		}
	} tr[N << 2];
	
	void pushup(int pos) {
		tr[pos].num = (tr[lson].num + tr[rson].num) % mod;
	}
	
	void pushdown(int pos, int l, int r) {
		int mid = (l + r) >> 1;
		tr[lson].num = (1ll * tr[lson].num * tr[pos].mul + 1ll * tr[pos].add * (mid - l + 1)) % mod;
		tr[rson].num = (1ll * tr[rson].num * tr[pos].mul + 1ll * tr[pos].add * (r - mid)) % mod;
		tr[lson].mul = (1ll * tr[lson].mul * tr[pos].mul) % mod;
		tr[rson].mul = (1ll * tr[rson].mul * tr[pos].mul) % mod;
		tr[lson].add = (1ll * tr[lson].add * tr[pos].mul + tr[pos].add) % mod;
		tr[rson].add = (1ll * tr[rson].add * tr[pos].mul + tr[pos].add) % mod;
		tr[pos].mul = 1;
		tr[pos].add = 0;
	}
	
	void build(int pos, int l, int r) {
		tr[pos].mul = 1;
		tr[pos].add = 0;
		if (l == r) {
			tr[pos].num = a[l];
			return ;
		}
		int mid = (l + r) >> 1;
		build(lson, l, mid);
		build(rson, mid + 1, r);
		pushup(pos);
	}
	
	void update_add(int pos, int l, int r, int x, int y, int val) {
		if (x <= l && r <= y) {
			tr[pos].add = (1ll * tr[pos].add + val) % mod;
			tr[pos].num = (1ll * tr[pos].num + 1ll * val * (r - l + 1)) % mod;
			return ;
		}
		int mid = (l + r) >> 1;
		pushdown(pos, l, r);
		if (x <= mid) {
			update_add(lson, l, mid, x, y, val);
		}
		if (y > mid) {
			update_add(rson, mid + 1, r, x, y, val);
		}
		pushup(pos);
	}
	
	void update_mul(int pos, int l, int r, int x, int y, int val) {
		if (x <= l && r <= y) {
			tr[pos].mul = (1ll * tr[pos].mul * val) % mod;
			tr[pos].add = (1ll * tr[pos].add * val) % mod;
			tr[pos].num = (1ll * tr[pos].num * val) % mod;
			return ;
		}
		int mid = (l + r) >> 1;
		pushdown(pos, l, r);
		if (x <= mid) {
			update_mul(lson, l, mid, x, y, val);
		}
		if (y > mid) {
			update_mul(rson, mid + 1, r, x, y, val);
		}
		pushup(pos);
	}
	
	int query(int pos, int l, int r, int x, int y) {
		if (x <= l && r <= y) {
			return tr[pos].num;
		}
		int mid = (l + r) >> 1;
		pushdown(pos, l, r);
		int ret = 0;
		if (x <= mid) {
			ret = (ret + 1ll * query(lson, l, mid, x, y)) % mod;
		}
		if (y > mid) {
			ret = (ret + 1ll * query(rson, mid + 1, r, x, y)) % mod;
		}
		return ret;
	}
	
	#undef lson
	#undef rson
	
} sgt;



int main() {
	scanf("%d%d%d", &n, &m, &mod);
	for (int i = 1; i <= n; i ++ ) {
		scanf("%d", &a[i]);
	}
	sgt.build(1, 1, n);
	for (int i = 1; i <= m; i ++ ) {
		int opt, x, y, k;
		scanf("%d%d%d", &opt, &x, &y);
		if (opt == 1) {
			scanf("%d", &k);
			sgt.update_mul(1, 1, n, x, y, k);
		}
		else if (opt == 2) {
			scanf("%d", &k);
			sgt.update_add(1, 1, n, x, y, k);
		}
		else {
			int ans = sgt.query(1, 1, n, x, y);
			printf("%d\n", ans);
		}
	}
	return 0;
}
posted @ 2019-11-15 15:49  筱柒_Littleseven  阅读(121)  评论(0编辑  收藏  举报