线段树 区间更新(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 ;} 

你可能感兴趣的:(poj)