且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

hdu 1698 Just a Hook

更新时间:2022-08-12 16:14:08

点击打开链接hdu1698


思路:线段树成段更新
分析:
1 成段更新和单点更新是不同的,单点更新是要更新到叶子节点,但是对于成段更新是更新到某个区间即可,找个区间是当前需要的更新的区间的最大的子区间
2 成段更新需要维护一个“延时标记”,初始化看情况。我们先把标记放在一个大的区间,下次遇到的时候再进行向下的更新(标记传递)
3 建好线段树然后更新,最后输出节点1的和即可

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int MAXN = 100010;
struct Node{
    int left;
    int right;
    int mark;
    int sum;
};
Node node[4*MAXN];
int N , Q;

//向上更新
void push_up(int pos){
    node[pos].sum = node[pos<<1].sum + node[(pos<<1)+1].sum;
}

//向下更新
void push_down(int pos){
    if(node[pos].mark){
       node[pos<<1].mark = node[pos].mark;
       node[(pos<<1)+1].mark = node[pos].mark;
       node[pos<<1].sum = node[pos<<1].mark*(node[pos<<1].right-node[pos<<1].left+1);
       node[(pos<<1)+1].sum = node[(pos<<1)+1].mark*(node[(pos<<1)+1].right-node[(pos<<1)+1].left+1);
       node[pos].mark = 0;
    }
}

//建立线段树
void buildTree(int left , int right , int pos){
    node[pos].left = left;
    node[pos].right = right;
    node[pos].mark = 1;
    if(left == right){
       node[pos].sum = 0;
       return;
    }
    int mid = (left+right)>>1;
    buildTree(left , mid , pos<<1);
    buildTree(mid+1 , right , (pos<<1)+1);
    push_up(pos);
}

//更新
void update(int left , int right , int value , int pos){
    if(left <= node[pos].left && right >= node[pos].right){
      node[pos].mark = value;
      node[pos].sum = value*(node[pos].right-node[pos].left+1);
      return;
    }
    push_down(pos);//向下更新
    int mid = (node[pos].left + node[pos].right)>>1;
    if(right <= mid)
       update(left , right , value , pos<<1);
    else if(left > mid)
       update(left , right , value , (pos<<1)+1);
    else{
       update(left , mid , value , pos<<1); 
       update(mid+1 , right , value , (pos<<1)+1);
    }
    push_up(pos);//向上更新
}

int main(){
    int tmp = 1;
    int Case , cntCase = 1;
    int x , y , value;
    scanf("%d" , &Case);
    while(Case--){
        scanf("%d%d" , &N , &Q);
        buildTree(1 , N , 1);
        while(Q--){
           scanf("%d%d%d" , &x , &y , &value);
           update(x , y , value , 1);
        }
        printf("Case %d: The total value of the hook is %d.\n" , cntCase++ , node[1].sum);
    }
    return 0;
}