HDU 1698 Just a Hook

  线段树成段更新的基础题,每次操作将x到y这个区间的值改为z,然后最后要求输出

的是1到n的区间和,根据线段树的性质,1到n的区间和其实就是sum[1]。

/*2012-08-08 16:07:20    Accepted    1698    1015MS    2280K    1407 B    G++    Yu*/

#include<stdio.h>



#define lson l, m, rt << 1

#define rson m + 1, r, rt << 1 | 1



const int MAXN = 100100;

int sum[MAXN << 2], col[MAXN << 2];

int n, q;



void PushUp(int rt)

{

    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];

}



void PushDown(int l, int r, int rt)

{

    int m = l + r >> 1;

    if(col[rt])

    {

        col[rt << 1] = col[rt << 1 | 1] = col[rt];

        sum[rt << 1] = (m - l + 1) * col[rt];

        sum[rt << 1 | 1] = (r - m) * col[rt];

        col[rt] = 0;

    }

}



void build(int l, int r, int rt)

{

    col[rt] = 0;

    sum[rt] = 1;

    if(l == r) return;

    int m = l + r >> 1;

    build(lson);

    build(rson);

    PushUp(rt);

}



void update(int L, int R, int c, int l, int r, int rt)

{

    int m = l + r >> 1;

    if(L <= l && r <= R)

    {

        col[rt] = c;

        sum[rt] = (r - l + 1) * c;

        return;

    }

    PushDown(l, r, rt);

    if(L <= m) update(L, R, c, lson);

    if(R > m) update(L, R, c, rson);

    PushUp(rt);

}



int main()

{

    int T, cas = 1, x, y, z;

    scanf("%d", &T);

    for(cas = 1; cas <= T; cas ++)

    {

        scanf("%d%d", &n, &q);

        build(1, n, 1);

        while(q --)

        {

            scanf("%d%d%d", &x, &y, &z);

            update(x, y, z, 1, n, 1);

        }

        printf("Case %d: The total value of the hook is %d.\n", cas, sum[1]);

    }

    return 0;

}

 

 

你可能感兴趣的:(HDU)