码迷,mamicode.com
首页 > 其他好文 > 详细

线段树(等级2,待进阶)

时间:2021-05-24 10:59:02      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:har   fine   等级   线段树   uil   for   register   long   进阶   

1.学了个标记永久化,用处有限,但是也有用
这里详解
code

#include <cstring>
#include <cstdio>
#include <algorithm>	
#define int long long		
#define R register int
#define printf tz1 = printf

using namespace std ;
const int N = 1e5 + 10 ;
typedef long long L ;
typedef double D ;

inline int read(){
	int w = 0 ; bool fg = 0 ; char ch = getchar() ;
	while( ch > ‘9‘ || ch < ‘0‘ ) fg |= ( ch == ‘-‘ ) , ch = getchar() ;
	while( ch >= ‘0‘ && ch <= ‘9‘ ) w = ( w << 1 ) + ( w << 3 ) + ( ch - ‘0‘ ) , ch = getchar() ;
	return fg ? -w : w ; 
}

int tz1 , n , m , c [N] , l , r , k , w ;
struct T{ int l , r , data , lz ; } t [N << 2] ;

void build( int x , int l , int r ){
	t [x].l = l , t [x].r = r ;
	if( l == r ){ t [x].data += c [l] ; return ; }
	int mid = ( l + r ) >> 1 ;
	build( x << 1 , l , mid ) ;
	build( x << 1 | 1 , mid + 1 , r ) ;
	t [x].data = t [x << 1].data + t [x << 1 | 1].data ; 
}

inline int ask( int x , int l , int r ){
//	printf( "ASK%lld %lld %lld %lld %lld %lld\n" , t [x].data , t [x].lz , l , r , t [x].l , t [x].r ) ;
	if( t [x].l >= l && t [x].r <= r ) return t [x].data + t [x].lz * ( t [x].r - t [x].l + 1 ) ; 
	int ans = t [x].lz * ( min( r , t [x].r ) - max( l , t [x].l ) + 1 ) ;
	int mid = ( t [x].l + t [x].r ) >> 1 ;
	if( l <= mid ) ans += ask ( x << 1 , l , r ) ;
	if( r > mid ) ans += ask ( x << 1 | 1 , l , r ) ;
	return ans ;
}

inline void add( int x , int l , int r , int k ){
//	printf( "%lld %lld %lld %lld %lld\n" , x , t [x].l , t [x].r , l , r ) ;
	if( t [x].l >= l && t [x].r <= r ){ t [x].lz += k ; return ; } 
	t [x].data += ( min( t [x].r , r ) - max( t [x].l , l ) + 1 ) * k ;
	int mid = ( t [x].l + t [x].r ) >> 1 ;
	if( l <= mid ) add( x << 1 , l , r , k ) ;
	if( r > mid ) add( x << 1 | 1 , l , r , k ) ;
}
 
void sc(){
	n = read() , m = read() ;
	for( R i = 1 ; i <= n ; i ++ ) c [i] = read() ;
	build( 1 , 1 , n ) ;
}

void work(){
	while( m -- ){
		int k = read() ;
		if( k == 1 ) l = read() , r = read() , w = read() , add( 1 , l , r , w ) ;
		else l = read() , r = read() , printf( "%lld\n" , ask( 1 , l , r ) ) ;
	}
}

signed main(){
	sc() ;
	work() ;
	return 0 ; 
}

2.权值线段树,动态开点,合并先挖个坑

线段树(等级2,待进阶)

标签:har   fine   等级   线段树   uil   for   register   long   进阶   

原文地址:https://www.cnblogs.com/TYubai/p/14772227.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!