codedecision P1112 区间连续段 题解 线段树
Posted codedecision
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codedecision P1112 区间连续段 题解 线段树相关的知识,希望对你有一定的参考价值。
题目描述:https://www.cnblogs.com/problems/p/P1112.html
题目链接:http://codedecision.com/problem/1112
线段树区间操作,每一个线段对应的点包含三个信息:
- (l):表示这个区间最左边的点的数值;
- (r):表示这个区间最右边的点的数值;
- (cnt):表示这个区间有多少个数值段。
合并的时候:
- 根节点的 (l) 值等于左儿子节点的 (l) 值;
- 根节点的 (r) 值等于右儿子节点的 (r) 值;
- 根节点的 (cnt) 值取决于左儿子的 (r) 值和右儿子的 (l) 值是否相等,
- 如果相等,则为:左儿子的 (cnt) + 右儿子的 (cnt) - 1
- 否则,为:左儿子的 (cnt) + 右儿子的 (cnt)
更新的时候,如果节点表示的这一段区间全在区间范围内,
则将节点的 (l) 和 (r) 都置为将要更新的值,并将节点的 (cnt) 置为 1。
因为涉及区间操作,需要用到延迟操作。
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100100;
struct Node {
int l, r, cnt;
Node () {}
Node (int _l, int _r, int _cnt) { l = _l; r = _r; cnt = _cnt; }
} tree[maxn<<2];
int n, lazy[maxn<<2];
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
void push_up(int rt) {
tree[rt].l = tree[rt<<1].l;
tree[rt].r = tree[rt<<1|1].r;
tree[rt].cnt = tree[rt<<1].cnt + tree[rt<<1|1].cnt - (tree[rt<<1].r == tree[rt<<1|1].l ? 1 : 0);
}
void push_down(int rt) {
if (lazy[rt]) {
lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
tree[rt<<1].cnt = tree[rt<<1|1].cnt = 1;
tree[rt<<1].l = tree[rt<<1].r = tree[rt<<1|1].l = tree[rt<<1|1].r = lazy[rt];
lazy[rt] = 0;
}
}
void build(int l, int r, int rt) {
if (l == r) {
tree[rt] = Node(0, 0, 1);
return;
}
int mid = (l + r) / 2;
build(lson);
build(rson);
push_up(rt);
}
void update(int L, int R, int v, int l, int r, int rt) {
if (l > r) {
printf("fuck %d > %d (%d)
", l, r, rt);
return;
}
if (rt >= maxn*2) {
printf("fuck rt big %d , %d (%d)
", l, r, rt);
return;
}
if (L <= l && r <= R) {
tree[rt] = Node(v, v, 1);
lazy[rt] = v;
return;
}
push_down(rt);
int mid = (l + r) / 2;
if (L <= mid) update(L, R, v, lson);
if (R > mid) update(L, R, v, rson);
push_up(rt);
}
Node query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) return tree[rt];
push_down(rt);
int mid = (l + r) / 2;
if (L > mid) return query(L, R, rson);
else if (R <= mid) return query(L, R, lson);
else {
Node a = query(L, R, lson);
Node b = query(L, R, rson);
return Node(a.l, b.r, a.cnt + b.cnt - (a.r == b.l ? 1 : 0));
}
}
int m, x, y, a;
string op;
int main() {
cin >> n >> m;
build(1, n, 1);
while (m --) {
cin >> op;
if (op == "update") {
cin >> x >> y >> a;
update(x, y, a, 1, n, 1);
}
else {
cin >> x >> y;
cout << query(x, y, 1, n, 1).cnt << endl;
}
}
return 0;
}
以上是关于codedecision P1112 区间连续段 题解 线段树的主要内容,如果未能解决你的问题,请参考以下文章