您的位置:首页 > 理论基础 > 数据结构算法

hdu 1698 Just a Hook(数据结构:线段树)

2014-08-03 23:06 357 查看
这个题就是说给你一个初始材质为铜的栅栏

每次更新一段材质为金或银或铜

金对应的一根栅栏价值为3

银对应的一根栅栏价值为2

铜对应的一根栅栏价值为1

让你输出最后的栅栏总价值

线段树区间更新,看到资料上说这里要用到延迟标记的概念

就是说当前依次更新,只更新了根节点的值,其子节点的值暂时不更新

等到下次可能访问子节点的时候才更新它的信息和父节点保持一致

毫无疑问这可以省去很多时间提高效率

我们用col表示材质,初始化为0,如果检测到当前的某个节点col值不为0, 则更新子节点和父节点信息保持一致

代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm>
#define MAXN 100100
#define LL long long
using namespace std;

struct Node {
int col, val;
}s[MAXN<<2];

void PushUp(int rt) {
s[rt].val = s[rt<<1].val + s[rt<<1|1].val;
}

void PushDown(int rt, int m) {
if(s[rt].col) {
s[rt<<1].col = s[rt<<1|1].col = s[rt].col;
s[rt<<1].val = s[rt<<1].col*(m-(m>>1));
s[rt<<1|1].val = s[rt<<1|1].col*(m>>1);
s[rt].col = 0;
}
}

void build(int l, int r, int rt) {
s[rt].col = 0;
s[rt].val = 1;
if(l == r)
return ;
int m = (l+r) >> 1;
build(l, m, rt<<1);
build(m+1, r, rt<<1|1);
PushUp(rt);
}

void update(int L, int R, int c, int l, int r, int rt) {
if(L<=l && r<=R) {
s[rt].col = c;
s[rt].val = c*(r-l+1);
return ;
}
PushDown(rt, r-l+1);
int m = (l+r) >> 1;
if(L <= m)
update(L, R, c, l, m, rt<<1);
if(R > m)
update(L, R, c, m+1, r, rt<<1|1);
PushUp(rt);
}

int main(void) {
int T, n, q, x, y, z;
scanf("%d", &T);
for(int t=1; t<=T; ++t) {
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", t, s[1].val);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: