线段树(区间更新与区间查询)——Just a Hook ( HDU 1698 )

来源:互联网 发布:mac 系统的 制谱软件 编辑:程序博客网 时间:2024/03/29 15:23
  • 题目链接:
    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 100005int 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);}
  • AC代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define lc (d<<1)#define rc (d<<1|1)#define mid ( l+r >>1)#define Max 100005int 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));    }}
0 0