线段树(等级2,待进阶)
Posted $mathcal{Yubai}$
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树(等级2,待进阶)相关的知识,希望对你有一定的参考价值。
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,待进阶)的主要内容,如果未能解决你的问题,请参考以下文章