很经典的题目,而且是标准的线段树增加lazy标志的入门题目。
做了好久线段树,果然是practice makes perfect, 这次很畅快,打完一次性AC了。
标志的线段树函数。
主要是:
更新的时候只更新到需要的节点,然后最后的时候一次性把所以节点都更新完毕。
这也是线段树常用的技术。
#include <stdio.h>
const int SIZE = 100005;
struct Node
{
bool lazy;
int metal;
};
const int TREESIZE = SIZE + (SIZE<<1);
Node segTree[TREESIZE];
inline int lChild(int rt) { return rt<<1;}
inline int rChild(int rt) { return rt<<1|1;}
void build(int l, int r, int rt)
{
segTree[rt].lazy = 0;
segTree[rt].metal = 1;
if (l == r) return ;//不要忘记这里返回!
int m = l + ((r-l)>>1);
build(l, m, lChild(rt));
build(m+1, r, rChild(rt));
}
inline void pushDown(int rt)
{
if (segTree[rt].lazy)
{
segTree[rt].lazy = false;//别忘记了
int id = lChild(rt);
segTree[id].lazy = true;
segTree[id].metal = segTree[rt].metal;
id = rChild(rt);
segTree[id].lazy = true;
segTree[id].metal = segTree[rt].metal;
}
}
void update(int metal,const int L, const int R, int l, int r, int rt)
{
if (L <= l && r <= R)
{
segTree[rt].lazy = true;
segTree[rt].metal = metal;
return;
}
if (r < L || R < l) return ;
pushDown(rt);
int m = l + ((r-l)>>1);
update(metal, L, R, l, m, lChild(rt));
update(metal, L, R, m+1, r, rChild(rt));
}
void query(int l, int r, int rt, int &res)
{
if (l == r)
{
res += segTree[rt].metal;
return ;
}
pushDown(rt);
int m = l + ((r-l)>>1);
query(l, m, lChild(rt), res);
query(m+1, r, rChild(rt), res);
}
int main()
{
int T, N, Q, x, y, z;
scanf("%d", &T);
for (int t = 1; t <= T; t++)
{
scanf("%d", &N);
build(1, N, 1);
scanf("%d", &Q);
while (Q--)
{
scanf("%d %d %d", &x, &y, &z);
update(z, x, y, 1, N, 1);
}
int res = 0;
query(1, N, 1, res);
printf("Case %d: The total value of the hook is %d.\n", t, res);
}
return 0;
}