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 }
我就是我,颜色不一样的烟火 --- geloutingyu