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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树(区间修改+区间查询)相关的知识,希望对你有一定的参考价值。

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 }

 

以上是关于线段树(区间修改+区间查询)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构线段树 (定义 & 点修改/区间查询)

模板线段树-单点修改,区间查询

线段树详解

线段树 建树 单点修改 点点/区间查询

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

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