HDU-1698 Just a Hook (线段树区间修改)

题意:给t个例子,n个值,m个寻问,每次对区间(l,r)进行修改 ,只能将其修改为1,2,3中的一种

思路:对于线段树 区间直接修改 与 区间每项相加 之间是有一些差别的,要理解透 push_down与lazy tag的意义

 

完整代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int t=0,n=0;
int seg[400010],tag[400010];
int m=0,x=0,y=0,k=0;//k为修改的值 

void build(int pos,int l,int r){
    if(l==r){
        seg[pos]=1;
        tag[pos]=0;
        return;
    }
    else{
        int mid=(l+r)/2;
        build(pos<<1,l,mid);
        build(pos<<1|1,mid+1,r);
        seg[pos]=seg[pos<<1]+seg[pos<<1|1];
    }
}

void down(int pos,int num){
    if(tag[pos]){
        seg[pos<<1]=tag[pos]*(num-num/2);
        seg[pos<<1|1]=tag[pos]*(num/2);//attention!
        tag[pos<<1]=tag[pos<<1|1]=tag[pos];
        tag[pos]=0;
    }
}

void update(int pos,int l,int r){
    if(x>r||y<l) return;
    if(x<=l&&y>=r){
        seg[pos]=k*(r-l+1);
        tag[pos]=k;
        return;
    }
    down(pos,r-l+1);
    int mid=(l+r)/2;
    update(pos<<1,l,mid);
    update(pos<<1|1,mid+1,r);
    seg[pos]=seg[pos<<1]+seg[pos<<1|1];
}

int main(){
    scanf("%d",&t);
    for(int i=1;i<=t;i++){
        memset(seg,0,sizeof(seg));
        memset(tag,0,sizeof(tag));
        scanf("%d",&n);
        build(1,1,n);
        scanf("%d",&m);
        for(int j=1;j<=m;j++){
            scanf("%d%d%d",&x,&y,&k);
            update(1,1,n);
        }
        printf("Case %d: The total value of the hook is %d.\n",i,seg[1]);
    }
    return 0;
}

 

posted @ 2019-07-25 17:53  Tianwell  阅读(188)  评论(0编辑  收藏  举报