zoukankan      html  css  js  c++  java
  • POJ A Simple Problem with Integers 线段树的成段更新

                                                                              A Simple Problem with Integers

    Description

    You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

    Input

    The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000. The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000. Each of the next Q lines represents an operation. "C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000. "Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

    Output

    You need to answer all Q commands in order. One answer in a line.

    Sample Input

    10 5
    1 2 3 4 5 6 7 8 9 10
    Q 4 4
    Q 1 10
    Q 2 4
    C 3 6 3
    Q 2 4
    

    Sample Output

    4
    55
    9
    15

    Hint

    The sums may exceed the range of 32-bit integers.
    /* 如果两个人的天堂 象是温馨的墙 囚禁你的梦想 幸福是否象是一扇铁窗 候鸟失去了南方*/
    
    #include<cstdio>
    #include<iostream>
    #define M 100010
    struct node{ int s , e  ; long long  add ,  sum  ; }qe[M*4] ;//数据太大 需要 long long 
    using namespace std ;
    long long  Max , sum ;
    void creat( int s , int e , int step ){ // 建树 
    	qe[step].s = s ; 
    	qe[step].e = e ;
    	qe[step].sum = 0 ;
    	qe[step].add = 0 ;
    	if( s == e ) return ;
    	int mid = ( s + e ) >> 1 ;
    	creat( s , mid , step << 1 ) ;
    	creat( mid + 1 ,e , step << 1 |1 ) ;
    }
    long long  ma( long long  a , long long  b ){
    	if( a > b ) return a ;
    	return b ;
    }
    void pushdown(int step , int s , int e )  
    {    
    	long long f = qe[step].add ;
        if( f )  
        {   int mid = ( s + e ) >> 1 ;
            qe[step<<1].add += f;  
            qe[step<<1|1].add += f ;  
            qe[step<<1].sum += f * ( qe[step<<1].e - qe[step<<1].s + 1 ) ; 
            qe[step<<1|1].sum += f * ( qe[step<<1|1].e - qe[step<<1|1].s + 1 ) ; 
            qe[step].add = 0 ;  // 已经更新 子树 所以需要置为 0 避免下次重复更新子节点
        }  
    }  
    void insert( long long  i , long long  mun , long long  step ){ // 把线段树初始化 
    	if( qe[step].s == qe[step].e  ){
    		qe[step].sum = mun ;
    		return ;
    	}
    	
    	int mid = ( qe[step].s + qe[step].e ) >> 1 ;
    	if( mid >= i )
    		insert( i , mun , step << 1 ) ;
    
    	else insert( i ,mun , step << 1 | 1 ) ;
    	qe[step].sum = qe[step<<1].sum + qe[step<<1|1].sum ;
    	return ;
    }
    void up( int s , int e , int add , int step ){
    
    	if( qe[step].s == s && qe[step].e == e ){
    		qe[step].add += add ;
    		qe[step].sum += ( add * ( e - s + 1 ) ) ;
    		return ;
    	}
    	pushdown( step ,s , e  ) ; // 如果 当前的 线段 qe[].add 不为 0 就一起向下更新 
    
    	int mid = ( qe[step].s + qe[step].e ) >> 1 ;
    	if( mid >= e ) up( s , e , add , step << 1 ) ;
    	else if( s > mid ) up( s , e , add , step << 1| 1 ) ;
    	else {
    		up( s , mid , add , step << 1 ) ;
    		up( mid + 1 , e , add , step <<1|1 ) ;
    	}
    	qe[step].sum = qe[step<<1].sum + qe[step<<1|1].sum ;//更新当前的 线段
    	return ;
    }
    long long  find( int s , int e ,int step ){
    	if( s == qe[step].s && e == qe[step].e ){	
    		return qe[step].sum ; 
    	}
    	 pushdown( step ,s , e ) ;// 查找的时候也要更新 
    	 int mid = ( qe[step]. s + qe[step].e ) >> 1 ;
    	 if( mid >= e ) return find( s , e , step << 1 ) ;
    	 else if( mid < s ) return find( s , e ,  step << 1 | 1 ) ;
    	 else {
    		return  find( s , mid , step << 1 ) + find( mid + 1 , e , step << 1 | 1 ) ;
    	 }
    }
    int main()
    {
    	int i , n , m , k , u , v ;
    	char o ;
    	//freopen( "in.txt" , "r" , stdin)
    	while( scanf( "%d%d" , &n , &m ) != EOF ){
    		  creat( 1 , n , 1 ) ;
    		for( i = 1 ; i <= n ;i++ ) {
    			scanf( "%d" , &u ) ;
    			insert( i , u , 1 ) ;
    		}
    		while( m-- ){
    			scanf( " %c" , &o ) ;
    			if( o == 'C' ){
    			scanf( "%d%d%d" , &u , &v ,&k ) ;
    			 up( u , v , k , 1 ) ;
    			}
    			else{  
    				Max = 0 ; sum = 0 ;
    				 scanf( "%d%d" , &u , &v ) ;
    				 printf( "%lld\n" , find( u , v , 1 ) ) ;
    			}
    		}
    	}
    }
    

      

    代码:
  • 相关阅读:
    ActionMQ
    解决Session共享
    Linux中使用keepalived高可用工具解决宕机问题
    Linux安装Nginx
    Nginx基础
    多线程(1)
    单例模式1(3)
    创建型模式5种(2)
    7原则(1)
    反射使用案例(2)
  • 原文地址:https://www.cnblogs.com/20120125llcai/p/3011115.html
Copyright © 2011-2022 走看看