線分樹(区間更新と区間照会)——Just a Hook(HDU 1698)
11205 ワード
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.
", tt++, query(1, 1, N, 1, N));
}
}