XTU1238:Segment Tree(线段树)

1 l r c:l~r区间的值改为c

2 l r c:l~r区间内所有比c大的值变为c

3 l r c:l~r区间内所有比c小的值变为c

4 l r:查询区间内最小与最大的数字


const int N = 200008 ;
typedef long long LL ;
const LL inf = 1000000000000000LL ;
LL mx[N<<2] , mi[N<<2] , add[N<<2]  ;
LL a[N] ;

void  up(int t){
      mx[t] = std::max(mx[t<<1] , mx[t<<1|1]) ;
      mi[t] = std::min(mi[t<<1] , mi[t<<1|1]) ;
}

void  down(int t){
      if(add[t]){
           mx[t<<1] += add[t] ;
           mi[t<<1] += add[t] ;
           add[t<<1] += add[t] ;

           mx[t<<1|1] += add[t] ;
           mi[t<<1|1] += add[t] ;
           add[t<<1|1] += add[t] ;

           add[t] = 0 ;
      }

      mx[t<<1] = std::min(mx[t<<1] ,  mx[t]) ;
      mx[t<<1] = std::max(mx[t<<1] , mi[t]) ;

      mx[t<<1|1] = std::min(mx[t<<1|1] ,  mx[t]) ;
      mx[t<<1|1] = std::max(mx[t<<1|1] , mi[t]) ;


      mi[t<<1] = std::min(mi[t<<1] , mx[t]) ;
      mi[t<<1] = std::max(mi[t<<1] , mi[t] );

      mi[t<<1|1] = std::min(mi[t<<1|1] , mx[t]) ;
      mi[t<<1|1] = std::max(mi[t<<1|1] , mi[t] );

}

void build(int t , int l , int r){
     add[t] = 0 ;
     if(l == r){
         mx[t] = mi[t] = a[l] ;
         return ;
     }
     int m = (l + r) >> 1 ;
     build(t<<1 , l , m) ;
     build(t<<1|1 , m+1 , r) ;
     up(t) ;
}

void updateAdd(int L , int R , LL c , int t , int l , int r){
     if(L <= l && r <= R){
          add[t] += c ;
          mx[t] += c ;
          mi[t] += c ;
          return ;
     }
     down(t) ;
     int m = (l + r) >> 1 ;
     if(L <= m) updateAdd(L , R , c , t<<1 , l , m) ;
     if(R > m)  updateAdd(L , R , c , t<<1|1 , m+1 , r) ;
     up(t) ;
}

void updateMin(int L , int R , LL c , int t , int l , int r){
     if(L <= l && r <= R){
           mx[t] = std::min(mx[t] , c) ;
           mi[t] = std::min(mi[t] , c) ;
           return ;
     }
     down(t) ;

     int m = (l + r) >> 1 ;
     if(L <= m)  updateMin(L , R , c , t<<1 , l , m) ;
     if(R > m)   updateMin(L , R , c , t<<1|1 , m+1 , r) ;
     up(t) ;
}


void updateMax(int L , int R , LL c , int t , int l , int r){
     if(L <= l && r <= R){
           mx[t] = std::max(mx[t] , c) ;
           mi[t] = std::max(mi[t] , c) ;
           return ;
     }
     down(t) ;

     int m = (l + r) >> 1 ;
     if(L <= m)  updateMax(L , R , c , t<<1 , l , m) ;
     if(R > m)   updateMax(L , R , c , t<<1|1 , m+1 , r) ;
     up(t) ;
}


std::pair<LL , LL> ask(int L , int R , int t , int l , int r){
    if(L <= l && r <= R) return  std::make_pair(mi[t],mx[t]) ;
    std::pair<LL , LL> res = std::make_pair(inf , -inf) ;
    down(t) ;
    int m = (l + r) >> 1 ;
    if(L <= m){
        std::pair<LL , LL> p  = ask(L , R , t<<1 , l , m) ;
        res.first = std::min(res.first , p.first) ;
        res.second = std::max(res.second , p.second) ;
    }
    if(R > m){
         std::pair<LL , LL> p  = ask(L , R , t<<1|1 , m+1 , r) ;
         res.first = std::min(res.first , p.first) ;
         res.second = std::max(res.second , p.second) ;
    }
    return res ;
}


你可能感兴趣的:(XTU1238:Segment Tree(线段树))