题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1698
分析&题解:不多说,这类水题都放模板
1.线段树标准预处理:
#define lc (d<<1)
#define rc (d<<1|1)
#define mid ( l+r >>1)
//l,r表示整个区间范围
2.建树:
#define Max 100005
int a[Max];
struct Tr
{
int sum, lz;//区间和,懒操作
}tr[Max<<2];
void Push(int root)
{
tr[d].sum = tr[lc].sum + tr[rc].sum;
}
void build (int root, int l, int r)
{
tr[root].lz = 0;
if( l == r )
{
tr[root].sum = a[l];
return ;
}
build(lc, l, mid);
build(rc, mid+1, r);
Push(root);
}
2.懒操作:因为是区间求和,所以区间更新后需要一步懒操作,更新整个区间的和:
void lazy(int root, int l, int r)
{//因为是更新操作,所以直接赋值
if(tr[root].lz)
{
tr[lc].lz = tr[root].lz;
tr[rc].lz = tr[root].lz;
tr[lc].sum = tr[root].lz*(mid-l+1);
tr[rc].sum = tr[root].lz*(r-mid);
tr[root].lz = 0;
}
}
3.区间更新:
void update (int root, int l, int r, int L, int R, int k)
{
if(l == L && r == R)//因为是更新操作,所以直接赋值
{
tr[root].lz = k;
tr[root].sum = k*(r-l+1);
return ;
}
lazy(root, l, r);
if( R <= mid) update(lc, l, mid, L, R, k);
else if(L > mid) update( rc, mid+1, r, L, R, k);
else
{
update(lc, l, mid, L, mid, k);
update(rc, mid+1, r, mid+1, R, k);
}
Push(root);
}
4.区间查询:
int query(int root, int l , int r, int L, int R )
{
if( l == L && r == R)
{
return tr[root].sum;
}
lazy(d, l, r);
if( R <= mid) return query(lc, l, mid, L, R);
else if (L > mid) return query( rc, mid+1, r, L, R);
else return query(lc, l, mid, L, mid) + query(rc, mid+1, r, mid+1, R);
}
#include
#include
#include
#include
using namespace std;
#define lc (d<<1)
#define rc (d<<1|1)
#define mid ( l+r >>1)
#define Max 100005
int a[Max];
struct Tr
{
int sum, lz;
}tr[Max<<2];
void Push(int d)
{
tr[d].sum = tr[lc].sum + tr[rc].sum;
}
void build (int d, int l, int r)
{
tr[d].lz = 0;
if( l == r )
{
tr[d].sum = a[l];
return ;
}
build(lc, l, mid);
build(rc, mid+1, r);
Push(d);
}
void lazy(int d, int l, int r)
{
if(tr[d].lz)
{
tr[lc].lz = tr[d].lz;
tr[rc].lz = tr[d].lz;
tr[lc].sum = tr[d].lz*(mid-l+1);
tr[rc].sum = tr[d].lz*(r-mid);
tr[d].lz = 0;
}
}
int query(int d, int l , int r, int L, int R )
{
if( l == L && r == R)
{
return tr[d].sum;
}
lazy(d, l, r);
if( R <= mid) return query(lc, l, mid, L, R);
else if (L > mid) return query( rc, mid+1, r, L, R);
else return query(lc, l, mid, L, mid) + query(rc, mid+1, r, mid+1, R);
}
void update (int d, int l, int r, int L, int R, int k)
{
if(l == L && r == R)
{
tr[d].lz = k;
tr[d].sum = k*(r-l+1);
return ;
}
lazy(d, l, r);
if( R <= mid) update(lc, l, mid, L, R, k);
else if(L > mid) update( rc, mid+1, r, L, R, k);
else
{
update(lc, l, mid, L, mid, k);
update(rc, mid+1, r, mid+1, R, k);
}
Push(d);
}
int main()
{
int T;
scanf("%d", &T);
int tt = 1;
while(T--)
{
int N,Q;
scanf("%d%d", &N, &Q);
for(int i=1;i<=N;i++)
a[i] = 1;
build(1, 1, N);
for(int i=1;i<=Q;i++)
{
int a,b,v;
scanf("%d%d%d", &a,&b,&v);
update(1, 1, N, a, b, v);
}
printf("Case %d: The total value of the hook is %d.\n", tt++, query(1, 1, N, 1, N));
}
}