zoukankan      html  css  js  c++  java
  • 线段树 区间更新(hdu1698) 区间合并(poj3667)


    区间更新用到的延迟标记,不过是在更新时只更新到最大父区间,不继续往下更新,把更新的状态记录下来。当访问到子区间时再根据相应记录及时更新,pushodown()。

    code:

    #include <cstdlib>
    #include <cctype>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <string>
    #include <iostream>
    #include <sstream>
    #include <set>
    #include <queue>
    #include <stack>
    #include <fstream>
    #include <iomanip>
    #include <bitset>
    #include <list>
    #include <ctime>
    using namespace std ;

    #define SET(arr, what)  memset(arr, what, sizeof(arr))
    #define FF(i, a)        for(i=0; i<a; i++)
    #define SD(a)           scanf("%d", &a)
    #define SSD(a, b)       scanf("%d%d", &a, &b)
    #define SF(a)           scanf("%lf", &a)
    #define SS(a)           scanf("%s", a)
    #define SLD(a)          scanf("%lld", &a)
    #define PF(a)           printf("%d\n", a)
    #define PPF(a, b)       printf("%d %d\n", a, b)
    #define SZ(arr)         (int)a.size()
    #define SWAP(a,b)       a=a xor b;b= a xor b;a=a xor b;
    #define read            freopen("in.txt", "r", stdin)
    #define write            freopen("out.txt", "w", stdout)
    #define MAX             1<<30
    #define ESP             1e-5
    #define lson            l, m, rt<<1
    #define rson            m+1, r, rt<<1|1
    template<class T> inline T sqr(T a){return a*a;}
    template<class T> inline void AMin(T &a,T b){if(a==-1||a>b)a=b;}
    template<class T> inline void AMax(T &a,T b){if(a<b)a=b;}
    template<class T> inline T Min(T a,T b){return a>b?b:a;}
    template<class T> inline T Max(T a,T b){return a>b?a:b;}
    const int maxn = 100001 ;
    int sum[maxn<<2] ;
    int val[maxn<<2] ;
    void pushup(int rt){
        sum[rt] = sum[rt<<1] + sum[rt<<1|1] ;
    }
    void pushdown(int rt, int cnt){
        if(val[rt]){
            val[rt<<1] = val[rt<<1|1] = val[rt] ;
            sum[rt<<1] = (cnt - (cnt>>1)) * val[rt] ;
            sum[rt<<1|1] = (cnt>>1) * val[rt] ;
            val[rt] = 0 ;//更新后修改缓存值为0,避免重复更新

        }
    }
    void build(int l, int r, int rt){
        val[rt] = 0 ;
        sum[rt] = 1 ;
        if(r==l)    return ;
        int m = (l + r) >> 1 ;
        build(lson) ;
        build(rson) ;
        pushup(rt) ;
    }
    void update(int L, int R, int c, int l, int r, int rt){
        if(L<=l&&r<=R){
            val[rt] = c ;
            sum[rt] = (r - l + 1) * c ;
            return ;
        }
        pushdown(rt, r-l+1) ;//用到子区间,根据父节点的val往下更新
        int m = (l + r) >> 1 ;
        if(L<=m)    update(L, R, c, lson) ;
        if(R>m)     update(L, R, c, rson) ;
        pushup(rt) ;
    }
    int main(){
        int t, n, i, j, m, a, b, c ;
        SD(t) ;
        FF(i, t){
            SSD(n, m) ;
            build(1, n, 1) ;
            while(m--){
                SSD(a, b) ;SD(c) ;
                update(a, b, c, 1, n, 1) ;
            }
            printf("Case %d: The total value of the hook is %d.\n", i+1, sum[1]) ;
        }
        return 0 ;
    }

    区间合并看的比较纠结,主要是开始没明白lsum和rsum的准确意义。在更新时也用到了延迟技术。

    code:

    #include <cstdlib>
    #include <cctype>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <string>
    #include <iostream>
    #include <sstream>
    #include <set>
    #include <queue>
    #include <stack>
    #include <fstream>
    #include <iomanip>
    #include <bitset>
    #include <list>
    #include <ctime>
    using namespace std ;

    #define SET(arr, what)  memset(arr, what, sizeof(arr))
    #define FF(i, a)        for(i=0; i<a; i++)
    #define SD(a)           scanf("%d", &a)
    #define SSD(a, b)       scanf("%d%d", &a, &b)
    #define SF(a)           scanf("%lf", &a)
    #define SS(a)           scanf("%s", a)
    #define SLD(a)          scanf("%lld", &a)
    #define PF(a)           printf("%d\n", a)
    #define PPF(a, b)       printf("%d %d\n", a, b)
    #define SZ(arr)         (int)a.size()
    #define SWAP(a,b)       a=a xor b;b= a xor b;a=a xor b;
    #define read            freopen("in.txt", "r", stdin)
    #define write            freopen("out.txt", "w", stdout)
    #define MAX             1<<30
    #define ESP             1e-5
    #define lson            l, m, rt<<1
    #define rson            m+1, r, rt<<1|1
    template<class T> inline T sqr(T a){return a*a;}
    template<class T> inline void AMin(T &a,T b){if(a==-1||a>b)a=b;}
    template<class T> inline void AMax(T &a,T b){if(a<b)a=b;}
    template<class T> inline T Min(T a,T b){return a>b?b:a;}
    template<class T> inline T Max(T a,T b){return a>b?a:b;}
    const int maxn = 50010 ;
    int msum[maxn<<2], lsum[maxn<<2], rsum[maxn<<2] ;
    int cover[maxn<<2] ;
    void pushup(int rt, int cnt){
        lsum[rt] = lsum[rt<<1] ;
        rsum[rt] = rsum[rt<<1|1] ;
        if(lsum[rt]==cnt-(cnt>>1)) lsum[rt] += lsum[rt<<1|1] ;
        if(rsum[rt]==(cnt>>1))     rsum[rt] += rsum[rt<<1] ;
        msum[rt] = Max(lsum[rt<<1|1]+rsum[rt<<1], Max(msum[rt<<1], msum[rt<<1|1])) ;
    }
    void pushdown(int rt, int cnt){
        if(cover[rt]!=-1){
            cover[rt<<1] = cover[rt<<1|1] = cover[rt] ;
            msum[rt<<1] = lsum[rt<<1] = rsum[rt<<1] = cover[rt] ? 0 : cnt - (cnt >> 1) ;
            msum[rt<<1|1] = lsum[rt<<1|1] = rsum[rt<<1|1] = cover[rt] ? 0 : (cnt >> 1) ;
            cover[rt] = -1 ;
        }
    }
    void build(int l, int r, int rt){
        msum[rt] = lsum[rt] = rsum[rt] = r - l + 1 ;
        cover[rt] = -1 ;
        if(l==r)    return ;
        int m = (l + r) >> 1 ;
        build(lson) ;
        build(rson) ;
    }
    void update(int L, int R, int c, int l, int r, int rt){
        if(L<=l&&r<=R){
            msum[rt] = lsum[rt] = rsum[rt] = c ? 0 : (r-l+1) ;
            cover[rt] = c ;
            return ;
        }
        pushdown(rt, r-l+1) ;
        int m = (r + l) >> 1 ;
        if(L<=m)    update(L, R, c, lson) ;
        if(m<R)     update(L, R, c, rson) ;
        pushup(rt, r-l+1) ;
    }
    int query(int w, int l, int r, int rt){
        if(l==r)    return l ;
        pushdown(rt, r-l+1) ;
        int m = (l + r) >> 1 ;
        if(msum[rt<<1]>=w)  return query(w, lson) ;//左区间满足
        else if(rsum[rt<<1]+lsum[rt<<1|1]>=w)   return m - rsum[rt<<1] + 1 ;//区间合并满足
        return query(w, rson) ;//只能右区间满足
    }
    int main(){
        int n, m, i, j, t, a, b, q ;
        while(~SSD(n, m)){
            build(1, n, 1) ;
            while(m--){
                SD(t) ;
                if(t==1){
                    SD(a) ;
                    if(msum[1]<a)   PF(0) ;
                    else{
                        q = query(a, 1, n, 1) ;
                        PF(q) ;
                        update(q, q+a-111, n, 1) ;
                    }
                }else{
                    SSD(a, b) ;
                    update(a, a+b-101, n, 1) ;
                }
            }
        }
        return 0 ;} 
  • 相关阅读:
    php基础语言
    cookie和setting
    php数据连接
    php连接sql
    php提交
    今天学习了php的数据类型
    第一天进入php,这只是自己的一个心情
    02-07 (2) 自连接
    内连接 和左连接查询 02-07 (1)
    out 和ref 的区别
  • 原文地址:https://www.cnblogs.com/xiaolongchase/p/2616631.html
Copyright © 2011-2022 走看看