您的位置:首页 > 其它

2017暑假训练之线段树

2017-08-23 20:02 232 查看
线段树优点在于可以用数组来实现树形结构,大大简化代码。

单点更新,区间查询

HDUOJ 1166 敌兵布阵 374ms
#define lson cur<<1, l, mid
#define rson cur<<1 | 1, mid+1, r
int n, a[maxn], sum[maxn << 2];

void pushup(int cur) {
sum[cur] = sum[cur << 1] + sum[cur << 1 | 1];
}

void build(int cur, int l, int r) {
if (l == r) sum[cur] = a[l];
else {
int mid = Mid(l, r);
build(lson);
build(rson);
pushup(cur);
}
}

void update(int i, int val, int cur, int l, int r) {
if (l == r) sum[cur] += val;
else {
int mid = Mid(l, r);
if (i <= mid) update(i, val, lson);
else update(i, val, rson);
pushup(cur);
}
//pushup(cur);pushup过程不应在更新值后进行,此时cur并无lson与rson
}

int query(int L, int R, int cur, int l, int r) {
if (L <= l && r <= R) return sum[cur];
int mid = Mid(l, r), ret = 0;
if (L <= mid) ret += query(L, R, lson);
if (R > mid) ret += query(L, R, rson);
return ret;
}

int main() {
int T, kase = 1;
SF(T);
while (T--) {
int n;
SF(n);
FOR(i, 1, n + 1) SF(a[i]);
build(1, 1, n);
char op[6];
int l, r;
printf("Case %d:\n", kase++);
while (scanf("%s", op) && strcmp(op, "End")) {
SFF(l, r);
if (op[0] == 'Q') PF(query(l, r, 1, 1, n));
else if (op[0] == 'S') update(l, -r, 1, 1, n);
else update(l, r, 1, 1, n);
}
}
return 0;
}
线段树求区间最值

HDUOJ 1754 I Hate It 1045ms
#define lson cur<<1, l, mid
#define rson cur<<1 | 1, mid+1, r
int n, a[maxn], sum[maxn << 2];

void pushup(int cur) {
sum[cur] = max(sum[cur << 1], sum[cur << 1 | 1]);
}

void build(int cur, int l, int r) {
if (l == r) sum[cur] = a[l];
else {
int mid = Mid(l, r);
build(lson);
build(rson);
pushup(cur);
}
}

void update(int i, int val, int cur, int l, int r) {
if (l == r) sum[cur] = val;
else {
int mid = Mid(l, r);
if (i <= mid) update(i, val, lson);
else update(i, val, rson);
pushup(cur);
}
}

int query(int L, int R, int cur, int l, int r) {
if (L <= l && r <= R) return sum[cur];
int mid = Mid(l, r), ret = 0;
if (L <= mid) ret = max(query(L, R, lson), ret);
if (R > mid) ret = max(query(L, R, rson), ret);
return ret;
}

int main() {
int q;
while (~SFF(n, q)) {
FOR(i, 1, n + 1) SF(a[i]);
build(1, 1, n);
char op[2];
int l, r;
while (q--) {
scanf("%s%d%d", op, &l, &r);
if (op[0] == 'Q') PF(query(l, r, 1, 1, n));
else update(l, r, 1, 1, n);
}
}
return 0;
}
非递归(雾)写法

HDUOJ 1754 I Hate It 1145ms
#define lson cur<<1, l, mid
#define rson cur<<1 | 1, mid+1, r
int _n, n, a[maxn], sum[maxn << 2];

void build() {
n = 1;
while (n < _n) n <<= 1;
//FOR(i, 1, 2 * n) sum[i] = 0;
FOR(i, 1, _n+1) sum[i+n-1] = a[i];
for (int i = n - 1; i >= 1; --i) sum[i] = max(sum[i << 1], sum[i << 1 | 1]);
}

void update(int i, int val) {
i += n - 1;
sum[i] = val;
while (i > 1) {
i >>= 1;
sum[i] = max(sum[i << 1], sum[i << 1 | 1]);
}
}

int query(int L, int R, int cur, int l, int r) {
if (L <= l && r <= R) return sum[cur];
int mid = Mid(l, r), ret = 0;
if (L <= mid) ret = max(query(L, R, lson), ret);
if (R > mid) ret = max(query(L, R, rson), ret);
return ret;
}

void debug() {
FOR(i, 1, 2*n) printf("%d ", sum[i]); putchar(10);
}

int main() {
//IN(); OUT();
int q;
while (~SFF(_n, q)) {
FOR(i, 1, _n + 1) SF(a[i]);
build();
char op[2];
int l, r;
while (q--) {
//debug();
scanf("%s%d%d", op, &l, &r);
if (op[0] == 'Q') PF(query(l, r, 1, 1, n));
else update(l, r);
}
}
return 0;
}
lazy数组,区间更新,区间查询

POJ 3468 A Simple Problem with Integers 1641ms
#define lson cur<<1, l, mid
#define rson cur<<1|1, mid+1, r
LL sum[maxn<<2];
int a[maxn], lazy[maxn<<2];

void PushUp(int cur) {
sum[cur] = sum[cur << 1] + sum[cur << 1 | 1];
}

void build(int cur, int l, int r) {
if (l == r) sum[cur] = a[l];
else {
int mid = Mid(l, r);
build(lson);
build(rson);
PushUp(cur);
}
}

void PushDown(int cur, int cntl, int cntr) {
if (lazy[cur]) {
lazy[cur << 1] += lazy[cur];
lazy[cur << 1 | 1] += lazy[cur];
sum[cur << 1] += (LL)cntl*lazy[cur];
sum[cur << 1 | 1] += (LL)cntr*lazy[cur];
lazy[cur] = 0;
}
}

void update(int L, int R, int val, int cur, int l, int r) {
if (L <= l && r <= R) sum[cur] += (r - l + 1)*(LL)val, lazy[cur] += val;
else {
int mid = Mid(l, r);
PushDown(cur, mid - l + 1, r - mid);
if (L <= mid) update(L, R, val, lson);
if (R > mid) update(L, R, val, rson);
PushUp(cur);
}
}

LL query(int L, int R, int cur, int l, int r) {
if (L <= l && r <= R) return sum[cur];
int mid = Mid(l, r);
LL ret = 0;
PushDown(cur, mid - l + 1, r - mid);
if (L <= mid) ret += query(L, R, lson);
if (R > mid) ret += query(L, R, rson);
return ret;
}

int main() {
int n, q;
while (SFF(n, q) == 2) {
FOR(i, 1, n + 1) SF(a[i]);
build(1, 1, n);
FOR(i, 0, q) {
getchar();
char op;
op = getchar();
int a, b;
SFF(a, b);
if (op == 'Q') printf("%lld\n", query(a, b, 1, 1, n));
else {
int c; SF(c);
update(a, b, c, 1, 1, n);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: