首页 > 代码库 > 线段树(区间修改+区间查询)

线段树(区间修改+区间查询)

qwq , ylx 问我要一份线段树的版 , 可我线段树一直是10分钟 ,从不写版 ,qwq ,还是放一份版在这 。

题目见:http://poj.org/problem?id=3468 

  1 #include <iostream>  2 #include <cstring>  3 #include <cstdlib>  4 #include <cstdio>  5 const int inf = 1<<30 , maxn = 100000 + 11 ;  6 using namespace std;  7 int n , q , cnt ;  8 struct id  9 { 10      long long  sum , lazy ; 11 }tree[maxn<<2] ; 12  13 long long int read(  ) { 14     char ch = getchar(  ) ; long long int ret = 0 , k = 1 ; 15     while( ch < 0 || ch > 9 ) { if( ch == - ) k = -1 ; ch = getchar(  ) ; } 16     while( ch >= 0 && ch <= 9 ) ret = ret * 10 + ch - 0 , ch = getchar(  ) ; 17     return ret * k ; 18 } 19  20  21  22 void set_lazy( int num , int l , int r ) 23 { 24     int m = r - l + 1 ;  25     if( tree[num].lazy ) 26     { 27         tree[num<<1].lazy += tree[num].lazy ; 28         tree[(num<<1)+1].lazy += tree[num].lazy ; 29         tree[num<<1].sum += tree[num].lazy * ( m - (m>>1) ) ; 30         tree[(num<<1)+1].sum += tree[num].lazy * ( m>>1 ) ; 31         tree[num].lazy = 0ll ; 32     } 33      34 } 35  36 void update( int l , int r , int num , int L , int R , int add ) 37 {  38     if( l == L && r == R ) 39     { 40         tree[num].sum += 1ll*add * ( R - L + 1 ) ; 41         tree[num].lazy += add ;  42         return ; 43     } 44     if( l == r ) return ; 45     set_lazy( num , l , r ) ;  46     int mid = l + ( ( r - l ) >> 1 ); 47     if( R <= mid ) update( l , mid , num<<1 , L , R , add ) ; 48     else if( L > mid ) update( mid+1 , r , (num<<1)+1 , L , R , add ) ; 49     else  50     { 51         update( l , mid , num<<1 , L , mid , add ) ; 52         update( mid+1 , r , (num<<1)+1 , mid+1 , R , add ) ;     53     } 54     tree[num].sum = tree[num<<1].sum + tree[(num<<1)+1].sum ; 55 } 56  57  58 long long int quer( int l , int r , int num , int L , int R ) 59 {  60     if( l == L && R == r ) return tree[num].sum ; 61     set_lazy( num , l , r ) ;  62     int mid = l + ( ( r - l ) >> 1 ) ; 63     if( R <= mid ) return quer( l , mid , num<<1 , L , R ) ; 64     else if( L > mid ) return quer( mid + 1 , r , (num<<1)+1 , L , R ) ; 65     else return quer( l  , mid  , num<<1 , L , mid ) + quer( mid+1 , r , (num<<1)+1 , mid+1 , R ) ; 66 } 67  68  69 void build( int num , int l , int r ) 70 { 71     tree[num].lazy = 0ll ; 72     if( l == r ) 73     { 74         tree[num].sum = read( ) ; 75         return ; 76     } 77     int mid = l + ( ( r - l ) >> 1 ) ; 78      79     build( num<<1 , l , mid ) ; 80     build( (num<<1)+1 , mid+1 , r ) ; 81     tree[num].sum = tree[num<<1].sum + tree[(num<<1)+1].sum ;  82 } 83  84 int main( ) 85 { 86     n = read( ) , q = read( ) ;  87     build( 1 , 1 , n  ) ; 88     for( int  x = 1 ; x <= q ; ++x ) 89     { 90         char a ; int b , c , d ; 91         scanf( "%s" , &a ) ; 92         b = read( ) , c = read( ) ; 93         if( a == C )  94         { 95             d = read( ) ; 96             update( 1 , n , 1 , b , c , d ) ; 97         } 98         if( a == Q ) 99         {100             printf( "%lld\n" , quer( 1 , n , 1 , b , c ) ) ;101         }102     }103 }

 

线段树(区间修改+区间查询)