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 }

时间: 2024-10-23 00:42:58

hdu1698(线段树区间替换模板)的相关文章

线段树 + 区间更新 + 模板 ---- poj 3468

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 59798   Accepted: 18237 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

POJ 2528——Mayor&#39;s posters——————【线段树区间替换、找存在的不同区间】

Mayor's posters Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2528 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been plac

HDU1698线段树区间更新

原题http://acm.hdu.edu.cn/showproblem.php?pid=1698 Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 16935    Accepted Submission(s): 8427 Problem Description In the game of DotA, Pudge

HDU 1698 Just a Hook(线段树区间替换)

题目地址:HDU 1698 区间替换裸题.同样利用lazy延迟标记数组,这里只是当lazy下放的时候把下面的lazy也全部改成lazy就好了. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #in

线段树区间修改模板

本来打算把大白书第三章一口气攻下来的,但是这个线段树也是卡了好久. 不敢过题太快,怕自己走马观花到头来结果什么都不会. 可也不能再拖了,在做题中也许有更多的体会. 模板一:1 L R v 表示区间[L, R]所有元素都加上v2 L R   表示查询区间[L, R]的sum, min, maxsumv[o]的定义为:如果只执行节点o及其子孙节点的中的add操作,节点o对应区间中所有数之和 1 //线段树区间修改 2 //1 L R v 表示区间[L, R]所有元素都加上v 3 //2 L R 表示

POJ-3468 - A Simple Problem with Integers(线段树区间更新模板)

http://poj.org/problem?id=3468 Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of

[HDU] 1698 Just a Hook [线段树区间替换]

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 18378    Accepted Submission(s): 9213 Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing f

线段树 区间更新模板

一个带区间修改的线段树求和模板: int MAXN = 100005; ll a[100005<<2],ans,p; struct Tree { ll l,r; ll sum,add,mul; } tree[100005<<2]; void pushdown(int tr,int len) { if(len==1) return; long long m=tree[tr].mul,a=tree[tr].add; tree[tr*2].sum=(tree[tr*2].sum*m%p+

线段树 (区间覆盖模板)

线段树 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b].因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度. 使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN).而未优化的空间复杂度为2N,因此有时需要离散化让空间压缩. 题目链接:  http://a