题意:初始1-n 值为1,有Q操作,每次可以把一段【l,r】 整段每个值变成 x,问最后的【1,n】总和。

线段树成段更新(基础题)

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include <iostream>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define debug(x) printf(#x"= %d\n",x);
#define N 100050
using namespace std;
int sum[N * 4];
int flag[N * 4];
void build(int l, int r, int i) {
    sum[i] = r - l + 1;
    flag[i] = 1;
    if (l != r) {
        int mid = (l + r) >> 1;
        build(l, mid, L(i));
        build(mid + 1, r, R(i));
    }
}
void pushdown(int i, int l, int r, int mid) {
    flag[L(i)] = flag[R(i)] = flag[i];
    sum[L(i)] = (mid - l + 1) * flag[i];
    sum[R(i)] = (r - mid) * flag[i];
    flag[i] = 0;
}
void update(int l, int r, int pl, int pr, int va, int i) {

    if (l >= pl && r <= pr) {
        flag[i] = va;
        sum[i] = (r - l + 1) * va;
        return;
    }
    int mid = (l + r) >> 1;
    if (flag[i])
        pushdown(i, l, r, mid);
    if (pl <= mid)
        update(l, mid, pl, pr, va, L(i));
    if (pr > mid)
        update(mid + 1, r, pl, pr, va, R(i));
    sum[i] = sum[L(i)] + sum[R(i)];
}
int main() {
    int n, q, ri = 0, tt;
    scanf("%d", &tt);
    while (tt--) {
        scanf("%d%d", &n, &q);
        build(1, n, 1);
        while (q--) {
            int x, y, z;
            scanf("%d%d%d", &x, &y, &z);
            update(1, n, x, y, z, 1);
        }
        printf("Case %d: The total value of the hook is %d.\n", ++ri, sum[1]);
    }
    return 0;
}

 

posted on 2014-07-28 18:29  L_Ecry  阅读(223)  评论(0编辑  收藏  举报