线段树系列-hdu-1698-Just a Hook-区间修改求总和

简单的区间修改求总和

#include
using namespace std;
struct seg{
    int l, r, v;               // v的值如果是-1则说明这条线段不是单色
}tree[410000];
void build(int l, int r, int k) {
    tree[k].l = l;
    tree[k].r = r;
    tree[k].v = 1;
    if(l == r) return;
    int mid = (l + r) >> 1;
    build(l, mid, 2*k);
    build(mid+1 , r, 2*k+1);
}
void update(int l, int r, int v, int k) {
    if(tree[k].v == v) return;                 // 如果颜色相同就直接返回
    if(tree[k].l == l && tree[k].r == r) {     // 如果就是目标区域就直接修改线段的值
        tree[k].v = v;
        return;
    }
    if(tree[k].v != -1) {                      //如果是纯色,因为修改后不是纯色,所以要继续修改子区间,
        tree[2*k].v = tree[k].v;               //所以子区间的值先赋值为原区间的值,原区间设置为杂色
        tree[2*k+1].v = tree[k].v;             //为后面的修改做准备
        tree[k].v = -1;
    }
    int mid = (tree[k].l + tree[k].r) >> 1;
    if(r <= mid) update(l, r, v, 2*k);
    else if(l > mid) update(l, r, v, 2*k+1);
    else {
        update(l, mid, v, 2*k);
        update(mid+1, r, v, 2*k+1);
    }

}
int query(int k) {
    if(tree[k].v != -1) {
        return tree[k].v * (tree[k].r - tree[k].l + 1);
    }
    else {
        return query(k*2) + query(k*2+1);
    }
}
int main()
{
    int t;
    int n, q;
    int x, y, v;
    int kase = 0;
    scanf("%d", &t);
    while(t--) {
        scanf("%d", &n);
        build(1, n, 1);
        scanf("%d", &q);
        for(int i = 1; i <= q; i++) {
            scanf("%d%d%d", &x, &y, &v);
            update(x, y, v, 1);
        }
        printf("Case %d: The total value of the hook is %d.\n", ++kase, query(1));
    }
    return 0;
}


你可能感兴趣的:(线段树)