线段树板子求调
查看原帖
线段树板子求调
205199
紪絽楼主2023/10/17 21:00

RT,板子都能写不好,输入都输不进去……

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

ll a[100001], add[400001], mul[400001], tree[400001];
ll n, q, mod;

void pushup(ll p)
{
	tree[p] = (tree[p << 1] + tree[p << 1 | 1]) % mod;	
} 

void pushdown(ll p, ll l, ll r)
{
	ll lc = (p << 1), rc = ((p << 1) | 1), mid = l + ((r - l) >> 1);
	if (mul[p] != 1)
	{
		mul[lc] *= mul[p], mul[rc] *= mul[p];
		mul[lc] %= mod, mul[rc] %= mod;
		add[lc] *= mul[p], add[rc] *= mul[p];
		add[lc] %= mod, add[rc] %= mod; 
		tree[lc] *= mul[p], tree[rc] *= mul[p];
		tree[lc] %= mod, tree[rc] %= mod; 
		mul[p] = 1;		 
	}
	if (add[p])
	{
		tree[lc] += add[p] * (mid - l + 1), tree[rc] += add[p] * (r - mid);
		tree[lc] %= mod, tree[rc] %= mod;
		add[lc] += add[p], add[rc] += add[p];
		add[lc] %= mod, add[rc] %= mod;
		add[p] = 0;
	}
	return ;
}

void build(ll L, ll R, ll p)
{
	mul[p] = 1;
	if (L == R)
	{
		tree[p] = a[L];
		return ;
	}
	ll mid = L + ((R - L) >> 1);
	build(L, mid, (p << 1)); build(mid + 1, R, ((p << 1) | 1));
	pushup(p);
	return ;
}

void addsum(ll L, ll R, ll l, ll r, ll p, ll k)
{
	ll mid = l + ((r - l) >> 1);
	if (L <= l && r <= R)
	{
		tree[p] += k * (r - l + 1), add[p] += k;
		tree[p] %= mod, add[p] %= mod;	
		return ;
	}
	pushdown(p, l, r);
	if (l <= mid)
		addsum(L, R, l, mid, (p << 1), k); 
	if (mid + 1 <= r)
		addsum(L, R, mid + 1, r, ((p << 1) | 1), k);
	return ; 
}

void times(ll L, ll R, ll l, ll r, ll p, ll k)
{
	ll mid = l + ((r - l) >> 1);
	if (L <= l && r <= R)
	{
		tree[p] *= k, add[p] *= k, mul[p] *= k;
		tree[p] %= mod, add[p] %= mod, mul[p] %= mod;
		return ;
	}
	pushdown(p, l, r);
	if (l <= mid)
		times(L, R, l, mid, (p << 1), k); 
	if (mid + 1 <= r)
		times(L, R, mid + 1, r, ((p << 1) | 1), k); 
}

ll getans(ll L, ll R, ll l, ll r, ll p)
{
	ll mid = l + ((r - l) >> 1), tot = 0;
	if (L <= l && r <= R)
		return tree[p];
	pushdown(p, l, r);
	if (l <= mid)
		tot += getans(L, R, l, mid, (p << 1)) % mod; 
	if (mid + 1 <= r)
		tot += getans(L, R, mid + 1, r, ((p << 1) | 1)) % mod;
	return tot % mod; 	
}

int main()
{
	cin >> n >> q >> mod;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	build(1, n, 1);

	for (int i = 1; i <= q; i++)
	{
		int op, x, y, k;
		cin >> op;
		if (op == 1)
		{
			cin >> x >> y >> k;
			times(x, y, 1, n, 1, k);	
		} 
		else if (op == 2)
		{
			cin >> x >> y >> k;
			addsum(x, y, 1, n, 1, k);				
		}
		else
		{
			cin >> x >> y;
			getans(x, y, 1, n, 1); 
		}
	}
	return 0;	
} 
2023/10/17 21:00
加载中...