hdu1698 区间更新

初写线段树的时候,印象最深的一道,有一个pushdown的操作,使我的tle变成了ac

题意

输入t,然后t组数据

输入n,m,n代表n个点上价值全是1的绳子,m代表m次操作

m行l,r,val  就是区间l,r变成val

求最后绳子总共价值

思路

线段树,懒人标记

#include<queue>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cmath>
#include<string>
#include<vector>
#include<functional>
#define inf 0x3f3f3f3f
#define mem(k,b) memset(k,b,sizeof(k))
#define ll long long
#define ls (x)<<1
#define rs (x)<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
using namespace std;
const int maxn = 100010;

int t, n, m, q, p, z;
int tree[maxn << 2], add[maxn << 2];

void pushup(int x) {
    tree[x] = tree[ls] + tree[rs];
    return;
}

void pushdown(int x, int len){
    if (add[x]){
        add[ls] = add[x];
        add[rs] = add[x];
        tree[ls] = add[x] * (len - (len >> 1));
        tree[rs] = add[x] * (len >> 1);
        add[x] = 0;
    }
}

void build(int x, int l, int r){
    add[x] = 0;
    if (l == r){
        tree[x] = 1;
        return;
    }
    int mid = (l + r) >> 1;
    build(lson); build(rson);
    pushup(x);
}

void xiugai(int x, int l, int r, int l1, int r1,int zhi1){
    if (l >= l1 && r<=r1){
        add[x] = zhi1;
        tree[x] = zhi1*(r - l + 1);
        return;
    }
    pushdown(x, r - l + 1);
    int mid = (l + r) >> 1;
    if (r1<= mid){
        xiugai(lson, l1, r1, zhi1);
    }
    else if (l1>mid){
        xiugai(rson, l1, r1, zhi1);
    }
    else{
        xiugai(lson, l1, mid, zhi1);
        xiugai(rson, mid + 1, r1, zhi1);
    }
    pushup(x);
}

int main(){
    int c = 1;
    scanf("%d",&t);
    while (t--){
        scanf("%d%d",&n,&m);
        build(1, 1, n);
        for (int i = 0; i < m; i++){
            scanf("%d%d%d",&q,&p,&z);
            xiugai(1, 1, n, q, p, z);
        }
        printf("Case %d: The total value of the hook is %d.
",c++,tree[1]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/luoyugongxi/p/12191792.html