社区讨论

初学线段树,思路应该较清晰,求调

P3373【模板】线段树 2参与者 5已保存回复 8

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
8 条
当前快照
1 份
快照标识符
@lo8x8n9b
此快照首次捕获于
2023/10/28 02:03
2 年前
此快照最后确认于
2023/10/28 02:03
2 年前
查看原帖
rt,一些变量名已在程序中标出。
CPP
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;

int n, m, p, a[N], lazy1[N << 2], lazy2[N << 2], sum[N << 2];
//lazy1 记录乘  lazy2 记录加 

int ls (int k) {
	return (k << 1);
}
int rs (int k) {
	return (k << 1 | 1);
}

void pushup (int k) {
	sum[k] = (sum[ls(k)] + sum[rs(k)]) % p;
}

void pushdown (int k, int ln, int rn) {
	sum[ls(k)] = (sum[ls(k)] * lazy2[ls(k)] + lazy1[k] * ln) % p;
	sum[rs(k)] = (sum[rs(k)] * lazy2[rs(k)] + lazy1[k] * rn) % p;
	
	lazy2[ls(k)] = (lazy2[ls(k)] * lazy2[k]) % p;
	lazy2[rs(k)] = (lazy2[rs(k)] * lazy2[k]) % p;
	lazy1[ls(k)] = (lazy1[ls(k)] * lazy2[k] + lazy1[k]) % p;
	lazy1[rs(k)] = (lazy1[rs(k)] * lazy2[k] + lazy1[k]) % p;
	
	lazy1[k] = 0;
	lazy2[k] = 1;
}

void build (int l, int r, int k) {
	lazy2[k] = 1;
	
	if (l == r) {
		sum[k] = a[l] % p;
		return ;
	}
	
	int mid = (l + r) >> 1;
	build (l, mid, ls(k));
	build (mid + 1, r, rs(k));
	
	pushup(k);
}

void updata1 (int L, int R, int v, int l, int r, int k) { //*
	if (L <= l and r <= R) {
		lazy1[k] = (lazy1[k] * v) % p;
		lazy2[k] = (lazy2[k] * v) % p;
		sum[k] = (sum[k] * v) % p;
		
		return ;
	}
	
	int mid = (l + r) >> 1;
	pushdown (k, mid - l + 1, r - mid);
	
	if (L <= mid) updata1 (L, R, v, l, mid, ls(k));
	if (R > mid) updata1 (L, R, v, mid + 1, r, rs(k));
	
	pushup (k);
}

void updata2 (int L, int R, int v, int l, int r, int k) { //+
	if (L <= l and r <= R) {
		lazy1[k] = (lazy1[k] + k) % p;
		sum[k] = (sum[k] + v * (r - l + 1)) % p;
		return ;
	}
	
	int mid = (l + r) >> 1;
	pushdown (k, mid - l + 1, r - mid);
	if (L <= mid) updata2 (L, R, v, l, mid, ls(k));
	if (R > mid) updata2 (L, R, v, mid + 1, r, rs(k));
	
	pushup (k);
}

int query (int L, int R, int l, int r, int k) {
	if (L <= l and r <= R) {
		return sum[k] % k;
	}
	
	int mid = (l + r) >> 1, res = 0;
	pushdown (k, mid - l + 1, r - mid);
	
	if (L <= mid) res = (res + query(L, R, l, mid, ls(k))) % p;
	if (R > mid) res = (res + query (L, R, mid + 1, r, rs(k))) % p;
	return res;
}

int main () {
	scanf ("%d%d%d", &n, &m, &p);
	for (int i = 1; i <= n; ++ i) scanf ("%d", &a[i]);
	
	while (m --) {
		int opt, x, y, k;
		scanf ("%d%d%d", &opt, &x, &y);
		
		if (opt == 1) {
			scanf ("%d", &k);
			updata1 (x, y, k, 1, n, 1);
		}
		
		else if (opt == 2) {
			scanf ("%d", &k);
			updata2 (x, y, k, 1, n, 1);
		}
		
		else {
			printf ("%d\n", query(x, y, 1, n, 1));
		}
	}
	
	return 0;
}

回复

8 条回复,欢迎继续交流。

正在加载回复...