指针线段树MLE,求卡空间!!
查看原帖
指针线段树MLE,求卡空间!!
519384
Link_Cut_Y楼主2023/2/9 20:28

内存池也开了,就是不过。。。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define T long long

using namespace std;

const int N = 500010, mod = 19260817;
int w[N], n, m, now;

struct Queries {
	int op, l, r, x;
}q[100010];
struct node {
    node *ls, *rs;
    int l, r;
    T sum, add, mul;
    node() { ls = rs = NULL; sum = add = 0; mul = 1; }
    int len() { return r - l + 1; }
    void pushup() { this -> sum = (ls -> sum + rs -> sum) % mod; }
    void push_add(T val) { (add += val) %= mod, (sum += this -> len() * val) %= mod; }
    void push_mul(T val) { (add *= val) %= mod, (sum *= val) %= mod, (mul *= val) %= mod; }
    void pushdown() {
    	if (mul != 1) ls -> push_mul(mul), rs -> push_mul(mul), mul = 1;
		if (add) ls -> push_add(add), rs -> push_add(add), add = 0;
	}
}pool[N * 4], *idx;

struct SegmentTree {
	private :
		node *rt;
		void build(node *u, int l, int r) {
			u -> l = l, u -> r = r;
			if (l == r) { u -> sum = w[r] % mod; return; }
			int mid = l + r >> 1;
			u -> ls = new(idx ++ )node(), u -> rs = new(idx ++ )node();
			build(u -> ls, l, mid), build(u -> rs, mid + 1, r);
			u -> pushup();
		}
		void Add(node *u, int l, int r, T val) {
			if (u -> l >= l && u -> r <= r) { return (void)u -> push_add(val); }
			u -> pushdown();
			int mid = u -> l + u -> r >> 1;
			if (l <= mid) Add(u -> ls, l, r, val);
			if (r > mid) Add(u -> rs, l, r, val);
			u -> pushup();
		}
		void Mul(node *u, int l, int r, T val) {
			if (u -> l >= l && u -> r <= r) { return (void)u -> push_mul(val); }
			u -> pushdown();
			int mid = u -> l + u -> r >> 1;
			if (l <= mid) Mul(u -> ls, l, r, val);
			if (r > mid) Mul(u -> rs, l, r, val);
			u -> pushup();
		}
		T query(node *u, int l, int r) {
			if (u -> l >= l && u -> r <= r) return u -> sum;
			u -> pushdown();
			int mid = u -> l + u -> r >> 1, ans = 0;
			if (l <= mid) (ans += query(u -> ls, l, r)) %= mod;
			if (r > mid) (ans += query(u -> rs, l, r)) %= mod;
			return ans;
		}
	public :
		void build() { rt = new(idx ++ )node(); build(rt, 1, n); }
		void Add(int l, int r, int val) { Add(rt, l, r, val); }
		void Mul(int l, int r, int val) { Mul(rt, l, r, val); }
		T query(int l, int r) { return query(rt, l, r); }
}tr[2];

int main() {
	idx = pool;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i ++ )
		scanf("%d", &w[i]);
	tr[0].build(), tr[1].build();
	
	q[0].op = 4;
	for (int i = 1; i <= m; i ++ ) {
		scanf("%d", &q[i].op);
		if (q[i].op == 1) scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].x), tr[now].Add(q[i].l, q[i].r, q[i].x);
		if (q[i].op == 2) scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].x), tr[now].Mul(q[i].l, q[i].r, q[i].x);
		if (q[i].op == 3) scanf("%d%d", &q[i].l, &q[i].r), printf("%lld\n", tr[now].query(q[i].l, q[i].r));
		if (q[i].op == 4) {
			for (int j = i - 1; q[j].op != 4; j -- )
				if (q[j].op == 1) tr[now ^ 1].Add(q[j].l, q[j].r, q[j].x);
				else if (q[j].op == 2) tr[now ^ 1].Mul(q[j].l, q[j].r, q[j].x);
			now ^= 1;
		}
	}
	return 0;
}
2023/2/9 20:28
加载中...