题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698
前几题练习单点更新,现在练习成段更新。
线段树成段更新,需要用到延迟标记。
其实延迟标记又分为完成时标记与未完成标记,我们只练习前者。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
#define Maxn 100005
#define lx (x<<1)
#define rx ((x<<1) | 1)
#define MID ((l + r)>>1)
int A[Maxn];
int S[Maxn<<2];
int D[Maxn<<2];
void pushUp(int x)
{
S[x] = S[lx] + S[rx];
}
void pushDown(int l,int r,int x)
{
if(D[x])
{
D[lx] = D[x];
D[rx] = D[x];
S[lx] = (MID-l+1)*D[x];
S[rx] = (r-MID)*D[x];
D[x] = 0;
}
}
void build(int l,int r,int x)
{
D[x] = 0;
if(l == r)
{
S[x] = 1;
return;
}
build(l,MID,lx);
build(MID+1,r,rx);
pushUp(x);
}
int query(int L,int R,int l,int r,int x)
{
int ans = 0;
if(L<=l && r<=R)
{
return S[x];
}
pushDown(l,r,x);
if(L<=MID) ans += query(L,R,l,MID,lx);
if(R>=MID+1) ans += query(L,R,MID+1,r,rx);
return ans;
}
void update(int L,int R,int d,int l,int r,int x)
{
if(L<=l && r<=R)
{
D[x] = d;
S[x] = (r - l + 1)*d;
return;
}
pushDown(l,r,x);
if(L<=MID) update(L,R,d,l,MID,lx);
if(MID+1<=R) update(L,R,d,MID+1,r,rx);
pushUp(x);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int t;
int n;
int q;
int x,y,kind;
int cas = 0;
scanf(" %d",&t);
while(t--)
{
cas++;
scanf(" %d",&n);
build(1,n,1);
scanf(" %d",&q);
while(q--)
{
scanf(" %d %d %d",&x,&y,&kind);
update(x,y,kind,1,n,1);
}
int ans = query(1,n,1,n,1);
printf("Case %d: The total value of the hook is %d.\n",cas,ans);
}
return 0;
}