洛谷 #2357. 守墓人
阿新 • • 發佈:2018-11-24
題意
守墓人會有幾個操作:
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;
}