1. 程式人生 > >洛谷 #2357. 守墓人

洛谷 #2357. 守墓人

題意

守墓人會有幾個操作:

1.將[l,r]這個區間所有的墓碑的風水值增加 k。

2.將主墓碑的風水值增加 k

3.將主墓碑的風水值減少 k

4.統計[l,r]這個區間所有的墓碑的風水值之和

5.求主墓碑的風水值

主墓為1

題解

線段樹,把主墓拎出來單獨算

除錯記錄

無~~(是真的啥都沒幹)~~

#include <cstdio>
#define maxn 200005

using namespace std;

int val[maxn], n, f;

struct node{
	int l, r, key, lazy;
}
a[maxn << 2]; void build(int cur, int l, int r){ a[cur].l = l, a[cur].r = r; a[cur].lazy = 0; if (l == r){ a[cur].key = val[l]; return; } int mid = (l + r) >> 1; build(cur << 1, l, mid); build(cur << 1 | 1, mid + 1, r); a[cur].key = a[cur << 1].key + a[cur <<
1 | 1].key; } void pushdown(int cur){ if (!a[cur].lazy) return; a[cur << 1].lazy += a[cur].lazy; a[cur << 1 | 1].lazy += a[cur].lazy; a[cur << 1].key += (a[cur << 1].r - a[cur << 1].l + 1) * a[cur].lazy; a[cur << 1 | 1].key += (a[cur << 1 | 1].r - a[cur <<
1 | 1].l + 1) * a[cur].lazy; a[cur].lazy = 0; } void update(int cur, int l, int r, int k){ if (a[cur].r < l || a[cur].l > r) return; if (a[cur].l >= l && a[cur].r <= r){ a[cur].key += (a[cur].r - a[cur].l + 1) * k; a[cur].lazy += k; return; } pushdown(cur); update(cur << 1, l, r, k); update(cur << 1 | 1, l, r, k); a[cur].key = a[cur << 1].key + a[cur << 1 | 1].key; } int Query(int cur, int l, int r){ if (a[cur].r < l || a[cur].l > r) return 0; if (a[cur].l >= l && a[cur].r <= r) return a[cur].key; pushdown(cur); return Query(cur << 1, l, r) + Query(cur << 1 | 1, l, r); } int main(){ scanf("%d%d", &n, &f); for (int i = 1; i <= n; i++) scanf("%d", &val[i]); build(1, 1, n); while (f--){ int opt, l, r, k; scanf("%d", &opt); if (opt == 1){ scanf("%d%d%d", &l, &r, &k); if (l == 1) val[1] += k, l++; if (l > r) continue; update(1, l, r, k); } if (opt == 2){ scanf("%d", &k); val[1] += k; } if (opt == 3){ scanf("%d", &k); val[1] -= k; } if (opt == 4){ scanf("%d%d", &l, &r); if (l == 1){ if (r == 1) printf("%d\n", val[1]); else printf("%d\n", Query(1, l + 1, r) + val[1]); } else printf("%d\n", Query(1, l, r)); } if (opt == 5) printf("%d\n", val[1]); } return 0; }