hdu1698(线段树区间替换模板)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1698

 

题意: 第一行输入 t 表 t 组测试数据, 对于每组测试数据, 第一行输入一个 n , 表示钩子有 n 节, 编号为 1 ~ n, 每节钩子的初始价值为 1 , 接下来输入一个 q,

接着 q 行输入, 每行格式为 l, r, x, 表示讲区间 [l, r] 内的钩子价值变成 x , 求最终的总价值;

 

思路: 线段树区间替换模板

 

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #define lson l, mid, rt << 1
 4 #define rson mid + 1, r, rt << 1 | 1
 5 using namespace std;
 6 
 7 const int MAXN = 1e5 + 10;
 8 int sum[MAXN << 2];
 9 int col[MAXN << 2];
10 
11 void push_up(int rt){//向上更新
12     sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
13 }
14 
15 void push_down(int rt, int m){
16     if(col[rt]){//若有标记,则将标记移向下一层
17         col[rt << 1] = col[rt << 1 | 1] = col[rt]; //将标记向下更新
18         sum[rt << 1] = (m - (m >> 1)) * col[rt];//更新左儿子
19         sum[rt << 1 | 1] = (m >> 1) * col[rt];//更新右儿子
20         col[rt] = 0; //已经更新过的取消标记
21     }
22 }
23 
24 void build(int l, int r, int rt){ //建树
25     col[rt] = 0;
26     sum[rt] = 1;
27     if(l == r) return;
28     int mid = (l + r) >> 1;
29     build(lson);
30     build(rson);
31     push_up(rt);
32 }
33 
34 void update(int L, int R, int key, int l, int r, int rt){ //区间替换
35     if(L <= l && R >= r){
36         col[rt] = key;//延时标记
37         sum[rt] = (r - l + 1) * key;
38         return;
39     }
40     push_down(rt, r - l + 1);//向下更新
41     int  mid = (l + r) >> 1;
42     if(L <= mid) update(L, R, key, lson);
43     if(R > mid) update(L, R, key, rson);
44     push_up(rt);//向上更新
45 }
46 
47 int main(void){
48     int t, n, q, x, y, z;
49     scanf("%d", &t);
50     for(int i = 1; i <= t; i++){
51         scanf("%d%d", &n, &q);
52         build(1, n, 1);
53         while(q--){
54             scanf("%d%d%d", &x, &y, &z);
55             update(x, y, z, 1, n, 1);
56         }
57         printf("Case %d: The total value of the hook is %d.\n", i, sum[1]);//求的是整个数组的和,所以不需要另外写query函数
58     }
59     return 0;
60 }
View Code

 

posted @ 2017-06-13 19:17  geloutingyu  阅读(206)  评论(0编辑  收藏  举报