一道线段树水题,考察区间更新求和
题目大意:
首先给出一个数T表示有多少组数据.接下来给一个数N,表示一共有多少根链子(也就是有多少个数),再给一个数Q,表示接下来有多少行描述.每行描述有三个数据
x,y,z,表示区间(x,y)中所有链子数值更新为z.最后求N根链子的合.数组初始所有值为1.
解题思路:
标准的线段树求和+区间更新.没什么好说的~
函数build(l,r,rt); 初始化线段树;
函数updata(L,R,x,l,r,rt); 更新区域;
源代码:
#include <myhead.h>
#define ROOT 1,n,1
#define SON L,R,x
const int N=100010;
int n;
int seg[N<<2],lazy[N<<2];
inline void pushUp(int rt)
{//向上更新
seg[rt]=seg[LL(rt)]+seg[RR(rt)];
}
void build(int l,int r,int rt)
{
lazy[rt]=0;
if(l==r) {
seg[rt]=1;
return ;
}
int mid=MID(l,r);
build(LSON);
build(RSON);
pushUp(rt);
}
inline void pushDown(int m,int rt)
{//向下更新
lazy[LL(rt)]=lazy[RR(rt)]=lazy[rt];
seg[LL(rt)]=(m-(m>>1))*lazy[rt];
seg[RR(rt)]=(m>>1)*lazy[rt];
lazy[rt]=0;
}
void updata(int L,int R,int x,int l,int r,int rt)
{
if(L<=l&&r<=R) {
seg[rt]=(r-l+1)*x;
lazy[rt]=x;
return ;
}
if(lazy[rt]) {//判断懒惰数组是否有值,是否需要更新区间
pushDown(r-l+1,rt);
}
int mid=MID(l,r);
if(L<=mid) updata(SON,LSON);
if(R>mid) updata(SON,RSON);
pushUp(rt);
}
void init()
{
scanf("%d",&n);
build(ROOT);
int t;
scanf("%d",&t);
while(t--) {
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
updata(x,y,z,ROOT);
}
}
int main()
{
int t,m=1;
scanf("%d",&t);
while(t--) {
init();
printf("Case %d: The total value of the hook is %d.\n",m++,seg[1]);
}
return 0;
}