题意:
线段树 + lazy
poj 3468 代码
#include <iostream>
#include <stdio.h>
#define ll long long
#define lson l, mid, pos << 1
#define rson mid + 1, r, pos << 1 | 1
using namespace std;
const int MAXN = 1e5 + 10;
ll tree[MAXN<<2]; //不能用满二叉树,因为会TLE
ll lazy[MAXN<<2]; //不可以用 bool 来存 lazy,因为更改区间是当前sum += 而不是当前sum =
void updata(int p){
tree[p] = tree[p<<1] + tree[p<<1|1];
}
void lazyopen(int p, int m){
if(lazy[p]){
lazy[p<<1] += lazy[p];
lazy[p<<1|1] += lazy[p];
tree[p<<1] += (m - (m >> 1)) * lazy[p];
tree[p<<1|1] += (m >> 1) * lazy[p];
lazy[p] = 0;
}
}
void build(int l, int r, int pos){
lazy[pos] = 0;
if(l == r){
scanf("%lld", &tree[pos]);
return;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
updata(pos);
}
void add(int L, int R, ll key, int l, int r, int pos){
if(L <= l && R >= r){
tree[pos] += (r - l + 1) * key;
lazy[pos] += key;
return;
}
lazyopen(pos, r - l + 1);
int mid = (l + r) >> 1;
if(L <= mid)
add(L, R, key, lson);
if(R > mid)
add(L, R, key, rson);
updata(pos);
}
ll find(int L, int R, int l, int r, int pos){
if(L <= l && R >= r)
return tree[pos];
lazyopen(pos, r - l + 1);
int mid = (l + r) >> 1;
ll ans = 0;
if(L <= mid)
ans += find(L, R, lson);
if(R > mid)
ans += find(L, R, rson);
return ans;
}
int main(){
int n, m;
char op;
int l, r;
ll z;
scanf("%d%d", &n, &m);
build(1, n, 1);
while(m--){
scanf(" %c", &op);
if(op == 'C'){
scanf("%d%d%lld", &l, &r, &z);
add(l, r, z, 1, n, 1);
}
else{
scanf("%d%d", &l, &r);
printf("%lld\n", find(l, r, 1, n, 1));
}
}
}
hdu 1698 代码
#include <bits/stdc++.h>
#define lson l, mid, pos << 1
#define rson mid + 1, r, pos << 1 | 1
using namespace std;
const int MAXN = 1e5 + 10;
int tree[MAXN<<2];
int lazy[MAXN<<2]; //可以用 bool 来存 lazy,因为更改的钩子区间不是当前长度 += 而是当前长度 =
void updata(int p){
tree[p] = tree[p<<1] + tree[p<<1|1];
}
void lazyopen(int p, int m){
if (lazy[p]){
tree[p<<1] = (m - (m>>1)) * lazy[p];
tree[p<<1|1] = (m>>1) * lazy[p];
lazy[p<<1] = lazy[p<<1|1] = lazy[p];
lazy[p] = 0;
}
}
void build(int l, int r, int pos){
lazy[pos] = 0;
if (l == r){
tree[pos] = 1;
return;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
updata(pos);
}
void add(int ll, int rr, int z, int l, int r, int pos){
if (ll <= l && rr >= r){
tree[pos] = (r - l + 1) * z;
lazy[pos] = z;
return;
}
lazyopen(pos, r - l + 1);
int mid = (l + r) >> 1;
if (mid >= ll)
add(ll, rr, z, lson);
if (mid < rr)
add(ll, rr, z, rson);
updata(pos);
}
int main(){
int t, n, m, l, r, z;
scanf("%d", &t);
for (int T = 1; T <= t; T++){
scanf("%d%d", &n, &m);
build(1, n, 1);
while (m--){
scanf("%d%d%d", &l, &r, &z);
add(l, r, z, 1, n, 1);
}
printf("Case %d: The total value of the hook is %d.\n", T, tree[1]);
}
return 0;
}
hdu 1166 代码
#include <bits/stdc++.h>
#define lson l, mid, pos << 1
#define rson mid + 1, r, pos << 1 | 1
using namespace std;
const int MAXN = 5e4 + 10;
int tree[MAXN<<2];
void updata(int p){
tree[p] = tree[p<<1] + tree[p<<1|1];
}
void build(int l, int r, int pos){
if (l == r){
scanf("%d", &tree[pos]);
return;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
updata(pos);
}
void add(int i, int v, int l, int r, int pos){
if (l == r){
tree[pos] += v;
return;
}
int mid = (l + r) >> 1;
if (mid >= i)
add(i, v, lson);
else
add(i, v, rson);
updata(pos);
}
int find(int ll, int rr, int l, int r, int pos){
if (ll <= l && rr >= r)
return tree[pos];
int mid = (l + r) >> 1;
int ans = 0;
if (mid >= ll)
ans += find (ll, rr, lson);
if (mid < rr)
ans += find (ll, rr, rson);
return ans;
}
int main(void){
int t, n, a, b;
char op[10];
scanf("%d", &t);
for (int T = 1; T <= t; T++){
printf("Case %d:\n", T);
scanf("%d", &n);
build(1, n, 1);
while (true){
scanf(" %s", op);
if (strcmp(op, "End") == 0)
break;
scanf("%d%d", &a, &b);
if (strcmp(op, "Add") == 0)
add(a, b, 1, n, 1);
else if (strcmp(op, "Sub") == 0)
add(a, -b, 1, n, 1);
else
printf("%d\n", find(a, b, 1, n, 1));
}
}
}