感觉线段树要好好练一练。。。跟着大牛的pdf吧。。
http://acm.hdu.edu.cn/showproblem.php?pid=1698
区间更新主要运用的是一个lazy操作,就是说每次更新的时候不要更新到底,运用lazy标志将更新延迟到下次更新或者是查询的时候。
题意:
每次可以修改一段区间的值,最后查询整个的和。(所以查询函数都可以不写了。直接查根节点。。)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 111111
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int laz[M<<2];
int sum[M<<2];
int n;
void pushup(int rt)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void pushdown(int rt,int len)
{
if(laz[rt])
{
laz[rt<<1] = laz[rt<<1|1] = laz[rt]; //将laz标志推下去
sum[rt<<1] = (len - (len>>1)) * laz[rt]; //更新子节点的值
sum[rt<<1|1] = (len>>1) * laz[rt];
laz[rt] = 0; //清除标志
}
}
void update(int a,int b,int c,int l,int r,int rt)
{
if(a <= l && r <= b)
{
laz[rt] = c;
sum[rt] = (r-l+1)*c;
return ;
}
pushdown(rt,r-l+1);
int m = (l+r)>>1;
if(a <= m) update(a,b,c,lson); //递归更新左儿子
if(b > m) update(a,b,c,rson); //右儿子
pushup(rt);
}
void build(int l,int r,int rt)
{
laz[rt] = 0; //初始化所有节点的laz标志
if(l == r)
{
sum[rt] = 1; //将叶子节点初始化为1
return ;
}
int m = (l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
int main()
{
int t;
scanf("%d",&t);
for(int cas = 1;cas <= t;cas++)
{
scanf("%d",&n);
build(1,n,1);
int Q;
scanf("%d",&Q);
while(Q--)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
update(a,b,c,1,n,1);
}
printf("Case %d: The total value of the hook is %d.\n",cas,sum[1]);
}
return 0;
}