HDU1698【屠夫的钩子】

具体细节在代码里面,算是一个区间修改,点查询吧。

成段更新(通常这对初学者来说是一道坎),

需要用到延迟标记(或者说懒惰标记),

简单来说就是每次更新的时候不要更新到底,

用延迟标记使得更新延迟到下次需要更新or询问到的时候


 

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

using namespace std;



#define lson rt<<1,l,m

#define rson rt<<1|1,m+1,r



const int maxn=100005;

int n;



int sum[maxn<<3];

int col[maxn<<3];



void Pushup(int rt)

{

  sum[rt]=sum[rt<<1]+sum[rt<<1|1];

}

void Pushdown(int rt,int m)

{

    if(col[rt])

    {

        col[rt<<1]=col[rt<<1|1]=col[rt];

        sum[rt<<1]=(m-(m>>1))*col[rt];

        sum[rt<<1|1]=(m>>1)*col[rt];

        col[rt]=0;//大注意2. 一定得记得改回来。

    }

}

void build(int rt,int l,int r)

{

    sum[rt]=1;

    if(l==r) return;

    int m=(l+r)>>1;

    build(lson);

    build(rson);

    Pushup(rt);

}

void update(int ql,int qr,int ch,int rt,int l,int r)

{

    if(ql<=l&&qr>=r)

    {

        col[rt]=ch;

        sum[rt]=ch*(r-l+1);

        return;

    }

    Pushdown(rt,r-l+1);//会执行这一步的前提是要修改的已经插入已经标记未传给子结点的



    int m=(l+r)>>1;

    if(ql<=m)

       update(ql,qr,ch,lson);

    if(qr>m)

        update(ql,qr,ch,rson);

    Pushup(rt);

}



int main()

{

    int case_num,qnum,a,b,c;

    scanf("%d",&case_num);

    for(int i=1;i<=case_num;i++)

    {

        //注意1.每次还真得memset,或在build里面加入 col[i]=0;

        memset(col,0,sizeof(col));

        scanf("%d",&n);

        build(1,1,n);



        //printf("%d\n",sum[1]);



        scanf("%d",&qnum);

        while(qnum--)

        {

            scanf("%d%d%d",&a,&b,&c);

            update(a,b,c,1,1,n);

            //printf("~%d %d %d %d\n",sum[1],col[1],col[2],col[3]);

        }

        printf("Case %d: The total value of the hook is %d.\n",i,sum[1]);

    }

    return 0;

}


 

 

你可能感兴趣的:(HDU)