Mxqz,线段树样例不过(悬一关)
查看原帖
Mxqz,线段树样例不过(悬一关)
748509
2huk楼主2023/7/16 20:29
#include <iostream>

using namespace std;

#define re register
#define il inline

const int N = 1e5 + 10;

il int  read() { re int x = 0; re bool f = true; re char c = getchar(); while (c < 48 || c > 57) { if (c == '-') f = false; c = getchar(); } while (c >= 48 && c <= 57) x = (x << 3) + (x << 1) + c - 48, c = getchar(); return f ? x : -x; }
il void write(int x) { if (x < 0) putchar('-'), x = -x; if (x > 9) write(x / 10); putchar(x % 10 + 48); }
il void wel(int x) { write(x), putchar('\n'); }

int n, q, p, a[N], op, x, y, k;

struct Tree
{
	int l, r, sum, mul, add;
}tr[N << 2];

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

void pushup(int u) { tr[u].sum = tr[ls(u)].sum + tr[rs(u)].sum; return; }
void pushdown(int u)
{
	Tree &root = tr[u], &left = tr[ls(u)], &right = tr[rs(u)];
	left.sum = (left.sum * root.mul + (root.add * (left.r - left.l + 1)) % p) % p;
	right.sum = (right.sum * root.mul + (root.add * (right.r - right.l + 1)) % p) % p;
	left.mul = (left.mul * root.mul) % p;
	right.mul = (right.mul * root.mul) % p;
	left.add = (left.add * root.mul + root.add) % p;
	right.add = (right.add * root.mul + root.add) % p;
	
	root.mul = 1, root.add = 0;
	return;
}

void build(int u, int l, int r)
{
	if (l == r)
	{
		tr[u] = {l, r, a[l], 1, 0};
		return;
	}
	tr[u] = {l, r};
	int mid = l + r >> 1;
	build(ls(u), 1, mid), build(rs(u), mid + 1, r);
	pushup(u);
	return;
}

void modify1(int u, int l, int r, int d)
{
	if (tr[u].l >= l && tr[u].r <= r)
	{
		tr[u].sum = (tr[u].sum * k) % p;
		tr[u].mul = (tr[u].mul * k) % p;
		tr[u].add = (tr[u].add * k) % p;
		return;
	}
	
	pushdown(u);
	int mid = tr[u].l + tr[u].r >> 1;
	if (l <= mid) modify1(ls(u), l, r, d);
	if (r > mid) modify1(rs(u), l, r, d);
	pushup(u);
	return;
}

void modify2(int u, int l, int r, int d)
{
	if (tr[u].l >= l && tr[u].r <= r)
	{
		tr[u].add = (tr[u].add + d) % p;
		tr[u].sum = (tr[u].sum + d * (tr[u].r - tr[u].r + 1)) % p;
		return;
	}
	
	pushdown(u);
	int mid = tr[u].l + tr[u].r >> 1;
	if (l <= mid) modify2(ls(u), l, r, d);
	if (r > mid)  modify2(rs(u), l, r, d);
	pushup(u);
	return;
}

int query(int u, int l, int r)
{
	if (tr[u].l >= l && tr[u].r <= r)
		return tr[u].sum;
	
	pushdown(u);
	int mid = tr[u].l + tr[u].r >> 1, res = 0;
	if (l <= mid) res = query(ls(u), l, r);
	if (r > mid) res = (res + query(rs(u), l, r)) % p;
	return res; 
}

signed main()
{
	n = read(), q = read(), p = read();
	
	for (re int i = 1; i <= n; ++ i )
		a[i] = read();
	
	build(1, 1, n);
	
	while (q -- )
	{
		op = read(), x = read(), y = read();
		if (op == 1)
		{
			k = read();
			modify1(1, x, y, k);
		}
		else if (op == 2)
		{
			k = read();
			modify2(1, x, y, k);
		}
		else
		{
			wel(query(1, x, y));
		}
	}
	
    return 0;
}
2023/7/16 20:29
加载中...