题意:一开始有n个1组成的数列,执行q此操作,每次操作给出x y z,表示把区间【x,y】内的所有数变成z,执行完q此操作后求整个数列的和
思路:直接套用区间更新线段树的模板,进行简单的更新值与求和操作
#include
#include
#include
#include
using namespace std;
const int maxn = 1e5 + 10;
int T, n, q, date[maxn], segTree[maxn<<2], lazy[maxn<<2];
void init() {
for (int i = 1; i <= n; i++) {
date[i] = 1;
}
for (int i = 1; i <= n<<2; i++) {
segTree[i] = 0;
lazy[i] = 0;
}
}
void pushup(int root) {
segTree[root] = segTree[root<<1] + segTree[root<<1|1];
}
void pushdown(int root, int cntL, int cntR) {
if (lazy[root]) {
lazy[root<<1] = lazy[root];
lazy[root<<1|1] = lazy[root];
segTree[root<<1] = lazy[root] * cntL;
segTree[root<<1|1] = lazy[root] * cntR;
lazy[root] = 0;
}
}
void build(int L, int R, int root) {
if (L == R) {
segTree[root] = date[L];
return;
}
int mid = (L + R)>>1;
build(L, mid, root<<1);
build(mid + 1, R, root<<1|1);
pushup(root);
}
void update_interval(int L, int R, int root, int uL, int uR, int val) {
if (uL <= L && R <= uR) {
segTree[root] = val * (R - L + 1);
lazy[root] = val;
return;
}
int mid = (L + R)>>1;
pushdown(root, mid - L + 1, R - mid);
if (uL <= mid) {
update_interval(L, mid, root<<1, uL, uR, val);
}
if (uR > mid) {
update_interval(mid + 1, R, root<<1|1, uL, uR, val);
}
pushup(root);
}
int query(int L, int R, int root, int qL, int qR) {
if (qL <= L && R <= qR) {
return segTree[root];
}
int mid = (L + R)>>1;
pushdown(root, mid - L + 1, R - mid);
int ans = 0;
if (qL <= mid) {
ans += query(L, mid, root<<1, qL, qR);
}
if (qR > mid) {
ans += query(mid + 1, R, root<<1|1, qL, qR);
}
return ans;
}
int main()
{
scanf("%d", &T);
for (int kase = 1; kase <= T; kase++) {
scanf("%d%d", &n, &q);
init();
build(1, n, 1);
while (q--) {
int a, b, c; scanf("%d %d %d", &a, &b, &c);
update_interval(1, n, 1, a, b, c);
}
printf("Case %d: The total value of the hook is %d.\n", kase, query(1, n, 1, 1, n));
}
return 0;
}