线段树模版求调(悬一关)
  • 板块学术版
  • 楼主BWsha2k
  • 当前回复2
  • 已保存回复2
  • 发布时间2025/1/30 18:36
  • 上次更新2025/1/31 11:22:10
查看原帖
线段树模版求调(悬一关)
666114
BWsha2k楼主2025/1/30 18:36

P2023,代码没压行。

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#define ll long long
#define ull unsigned long long
using namespace std;

struct Node
{
	ll sum, plus = 0, mul = 1;
};

const int MAXN = 1e5+55;
ll n, m, op, x, y, z, a[MAXN], modb;
Node tree[4*MAXN];

inline ll ls(ll p) { return p << 1; }

inline ll rs(ll p) { return (p << 1) | 1; }

void pushup(ll p)
{
	tree[p].sum = (tree[ls(p)].sum + tree[rs(p)].sum) % modb;
	return;
}

void f(ll l, ll r, ll p, ll fa)
{
	tree[p].mul = (tree[p].mul * tree[fa].mul) % modb;
	tree[p].plus = (tree[p].plus + tree[fa].plus) % modb;
	tree[p].sum = (tree[p].sum * tree[fa].mul) % modb;
	tree[p].sum = (tree[p].sum + (tree[fa].plus * (r-l+1)) % modb) % modb;
	return;
}

void pushdown(ll l, ll r, ll p)
{
	ll mid = (l+r) / 2;
	f(l, mid, ls(p), p);
	f(mid+1, r, rs(p), p);
	tree[p].plus = 0, tree[p].mul = 1;
	return;
}

void build(ll l, ll r, ll p)
{
	if(l == r)
	{
		tree[p].sum = a[l] % modb;
		return;
	}
	ll mid = (l+r) / 2;
	build(l, mid, ls(p));
	build(mid+1, r, rs(p));
	pushup(p);
}

void opplus(ll l, ll r, ll p)
{
	if(l >= x && r <= y)
	{
		tree[p].sum = (tree[p].sum + z * (r-l+1)) % modb;
		tree[p].plus = (tree[p].plus + z) % modb;
		return;
	}
	pushdown(l, r, p);
	int mid = (l+r) / 2;
	if(x <= mid) opplus(l, mid, ls(p));
	if(y > mid) opplus(mid+1, r, rs(p));
	pushup(p);
}

void opmul(ll l, ll r, ll p)
{
	if(l >= x && r <= y)
	{
		tree[p].sum = (tree[p].sum * z) % modb;
		tree[p].mul = (tree[p].mul * z) % modb;
		tree[p].plus = (tree[p].plus * z) % modb;
		return;
	}
	pushdown(l, r, p);
	int mid = (l+r) / 2;
	if(x <= mid) opmul(l, mid, ls(p));
	if(y > mid) opmul(mid+1, r, rs(p));
	pushup(p);
}

ll query(ll l, ll r, ll p)
{
	if(l >= x && r <= y)
	{
		return tree[p].sum % modb;
	}
	ll res = 0;
	pushdown(l, r, p);
	int mid = (l+r) / 2;
	if(x <= mid) res += query(l, mid, ls(p)) % modb;
	if(y > mid) res += query(mid+1, r, rs(p)) % modb;
	return res % modb;
}

void solve()
{
	if(op == 1)
	{
		cin >> x >> y >> z;
		opmul(1, n, 1);
	}
	else if(op == 2)
	{
		cin >> x >> y >> z;
		opplus(1, n, 1);
	}
	else
	{
		cin >> x >> y;
		cout << query(1, n, 1) << endl;
	}
	return;
}

int main()
{
//  freopen(".in", "r", stdin);
//  freopen(".out", "w", stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> modb;
	for(int i = 1;i <= n;i++) cin >> a[i];
	build(1, n, 1);
	cin >> m;
	while(m--)
	{
		cin >> op;
		solve();
	}
	return 0;
}
2025/1/30 18:36
加载中...