标记永久化
查看原帖
标记永久化
129562
XYY1411楼主2021/4/6 17:42

写挂了,不知道为啥qwq

永久化 00 pts。

typedef long long ll;
inline int ls(int f) { return f << 1; }
inline int rs(int f) { return f << 1 | 1; }
inline int mid(int l, int r) { return (l + r) >> 1; }
const int maxn = 1e5 + 5;
ll a[maxn];
struct node {
    ll v;
    ll add;
    node() : add(0) {}
} st[maxn << 2];
inline void push_up(int p) { st[p].v = st[ls(p)].v + st[rs(p)].v; }
void build(int p, int l, int r) {
    if (l == r)
        st[p].v = a[l];
    else {
        int m = mid(l, r);
        build(ls(p), l, m);
        build(rs(p), m + 1, r);
        push_up(p);
    }
}

void plus(int p, int nl, int nr, int cl, int cr, ll k) {
    if (nr < cl || cr < nl) return;
    if (cl <= nl && nr <= cr) {
        st[p].v = st[p].v + k * (nr - nl + 1);
        st[p].add = st[p].add + k;
        return;
    }
    int m = mid(nl, nr);
    plus(ls(p), nl, m, cl, cr, k);
    plus(rs(p), m + 1, nr, cl, cr, k);
}
ll query(int p, int nl, int nr, int ql, int qr, ll tag) {
    if (nr < ql || qr < nl) return 0;
    if (ql <= nl && nr <= qr) return st[p].v + tag * (nr - nl + 1);
    int m = mid(nl, nr);
    return query(ls(p), nl, m, ql, qr, tag + st[p].add) +
           query(rs(p), m + 1, nr, ql, qr, tag + st[p].add);
}
int n, m, l, r, op;
ll k;
#include <cstdio>
using namespace std;
int main(void) {
    scanf("%d%d", &n, &m);
    for (register int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
    build(1, 1, n);
    while (m--) {
        scanf("%d%d%d", &op, &l, &r);
        switch (op) {
            case 1:
                scanf("%lld", &k);
                plus(1, 1, n, l, r, k);
                break;
            case 2:
                printf("%lld\n", query(1, 1, n, l, r, 0));
                break;
        }
    }
    return 0;
}

非永久化 100100 pts

typedef long long ll;
inline int ls(int f) {return f << 1;}
inline int rs(int f) {return f << 1 | 1;}
inline int mid(int l, int r) {return (l + r) >> 1;}
const int maxn = 1e5 + 5;
ll a[maxn];
struct node {
	ll v;
	ll add;
	node() : add(0){}
} st[maxn << 2];
inline void push_up(int p) {st[p].v = st[ls(p)].v + st[rs(p)].v;}
void build(int p, int l, int r) {
	if(l == r)
		st[p].v = a[l];
	else {
		int m = mid(l, r);
		build(ls(p), l, m);
		build(rs(p), m + 1, r);
		push_up(p);
	}
}
inline void push_down(int p, int l, int r) {
	int m = mid(l ,r);
	st[ls(p)].v += st[p].add * (m - l + 1);
	st[rs(p)].v += st[p].add * (r - m);
	st[ls(p)].add += st[p].add;
	st[rs(p)].add += st[p].add;
    st[p].add = 0;
}

void plus(int p, int nl, int nr, int cl, int cr, ll k) {
	if (nr < cl || cr < nl) return;
	if (cl <= nl && nr <= cr) {
		st[p].v = st[p].v + k * (nr - nl + 1);
		st[p].add = st[p].add + k;
		return ;
	}
	push_down(p, nl, nr);
	int m = mid(nl, nr);
	plus(ls(p), nl, m, cl, cr, k);
	plus(rs(p), m + 1, nr, cl, cr, k);
	push_up(p);
}
ll query(int p, int nl, int nr, int ql, int qr) {
	if (nr < ql || qr < nl) return 0;
	if (ql <= nl && nr <= qr) return st[p].v;
	push_down(p, nl, nr);
	int m = mid(nl, nr);
	return query(ls(p), nl, m, ql, qr) + query(rs(p), m + 1, nr, ql, qr);
}
int n, m, l, r, op;
ll k;
#include <cstdio>
using namespace std;
int main(void) {
	scanf("%d%d", &n, &m);
	for (register int i = 1; i <= n; ++i)
		scanf("%lld", &a[i]);
		build(1, 1, n);
		while (m--) {
			scanf("%d%d%d", &op, &l, &r);
			switch (op) {
				case 1:scanf("%lld", &k);plus(1, 1, n, l, r, k);break;
				case 2:printf("%lld\n", query(1, 1, n, l, r));break;
			}
		}
	return 0;
}
2021/4/6 17:42
加载中...