给定 N, Q,代表序列有 N 个元素,他们的初始值皆是 1。 接下來 Q 行,每行有三个数字 X, Y, Z,代表将序列中 X 到 Y 的元素值改成 Z。 最后输出序列元素的和。
Input
多組测试,第一个数字 T 代表有几组测试。 对于每一组测试,第一行会输入一个数字 N (1<=N<=100,000),下一行会输入一个数字 Q (0<=Q<=100,000)。
接下来 Q 行,每行有三个数字 X, Y, Z (1<=X<=Y<=N, 1<=Z<=3)
Output
对于每一次测试,输出一个数字代表序列每个元素的总和,格式请参考样例输出
区间修改,需要使用lazy标记提高效率。
#include<iostream>
using namespace std;
typedef long long LL;
const LL N = 1e5 + 10;
struct Tree {
LL l, r;
LL sum, f;
}t[N << 2];
void build(int p, int l, int r) {
t[p] = {l, r, 1, 0};
if (l == r) {
return;
}
LL mid = l + r >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
t[p].sum = t[p << 1].sum + t[p << 1 | 1].sum;
}
void down(int p) {
t[p << 1].f = t[p].f;
t[p << 1 | 1].f = t[p].f;
t[p << 1].sum = t[p].f * (t[p << 1].r - t[p << 1].l + 1);
t[p << 1 | 1].sum = t[p].f * (t[p << 1 | 1].r - t[p << 1 | 1].l + 1);
t[p].f = 0;
}
void change(int p, int l, int r, int v) {
if (l <= t[p].l && t[p].r <= r) {
t[p].sum = (t[p].r - t[p].l + 1) * v;
t[p].f = v;
return;
}
if (t[p].f) {
down(p);
}
LL mid = t[p].l + t[p].r >> 1;
if (l <= mid) {
change(p << 1, l, r, v);
}
if (r > mid) {
change(p << 1 | 1, l, r, v);
}
t[p].sum = t[p << 1].sum + t[p << 1 | 1].sum;
}
int query(int p, int l, int r) {
if (l <= t[p].l && t[p].r <= r) {
return t[p].sum;
}
if (t[p].f) {
down(p);
}
LL mid = t[p].l + t[p].r >> 1;
LL ans = 0;
if (l <= mid) {
ans += query(p << 1, l, r);
}
if (r > mid) {
ans += query(p << 1 | 1, l, r);
}
return ans;
}
int main() {
int T;
scanf("%d", &T);
int c = 0;
while(T --) {
int n, k;
c ++;
scanf("%d%d", &n, &k);
build(1, 1, n);
while(k --) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
change(1, x, y, z);
}
LL res = query(1, 1, n);
printf("Case %d: The total value of the hook is %d.\n", c, res);
}
return 0;
}