P3372 【模板】线段树 1
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 +10;
struct node
{
int l ,r ;
long long sum ,add ;
}tr[N * 4 ] ;
int w[N] ;
int n, q ;
void push_up(int u )
{
tr[u].sum = tr[u << 1 ].sum + tr[u << 1 |1 ].sum ;
}
void build(int u , int l , int r )
{
if( l == r )
{
tr[u] = {l , r , w[l]} ;
return ;
}
tr[u] = {l , r } ;
int mid = l + r >> 1 ;
build(u << 1 , l ,mid ) , build(u << 1 | 1 ,mid + 1 , r ) ;
push_up(u) ;
}
void push_down(int u )
{
if(tr[u].add != 0 )
{
tr[u << 1 ].sum += (long long )(tr[u << 1].r - tr[u << 1 ].l + 1 )*tr[u].add ;
tr[u << 1 | 1 ].sum += (long long) (tr[u << 1 |1].r - tr[u<< 1 | 1].l + 1 ) *tr[u].add ;
tr[u << 1 ].add += tr[u].add ;
tr[u << 1 | 1 ].add +=tr[u].add ;
tr[u].add = 0 ;
}
}
void modify(int u , int l , int r ,int d )
{
if(tr[u].l >= l && tr[u].r <= r)
{
tr[u].sum += (long long )(tr[u].r - tr[u].l+ 1 ) * d ;
tr[u].add += d;
return ;
}
int mid = tr[u].l + tr[u].r >> 1 ;
push_down(u) ;
if(mid >= l ) modify(u << 1 , l , r ,d );
if(mid < r ) modify(u << 1 | 1 , l , r , d ) ;
push_up(u) ;
}
long long query(int u , int l , int r)
{
if(tr[u].l >= l && tr[u].r <= r ) return tr[u].sum ;
push_down(u ) ;
int mid = tr[u].l + tr[u].r >> 1 ;
long long ans = 0 ;
if(l <= mid ) ans += query(u <<1 , l , r ) ;
if( r > mid ) ans += query(u << 1 |1 , l , r ) ;
return ans ;
}
int main()
{
cin>>n>>q;
for(int i = 1 ; i <= n; i ++ )cin>>w[i] ;
build(1 , 1 , n ) ;
string op;
while(q -- )
{
cin>>op;
if(op == "1" )
{
int l ,r , d ;
cin>>l >>r >>d ;
modify(1 , l , r , d ) ;
}
else
{
int l ,r ;
cin>>l >>r ;
cout<<query(1 , l , r ) <<endl;
}
}
return 0 ;
}
#个人学习