分析
树状数组
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010 ;
int n, m;
int a[ N] ;
LL tr1[ N] ;
LL tr2[ N] ;
int lowbit ( int x)
{
return x & - x;
}
void add ( LL tr[ ] , int x, LL c)
{
for ( int i = x; i <= n; i + = lowbit ( i) ) tr[ i] + = c;
}
LL sum ( LL tr[ ] , int x)
{
LL res = 0 ;
for ( int i = x; i; i - = lowbit ( i) ) res + = tr[ i] ;
return res;
}
LL prefix_sum ( int x)
{
return sum ( tr1, x) * ( x + 1 ) - sum ( tr2, x) ;
}
int main ( )
{
scanf ( "%d%d" , & n, & m) ;
for ( int i = 1 ; i <= n; i ++ ) scanf ( "%d" , & a[ i] ) ;
for ( int i = 1 ; i <= n; i ++ )
{
int b = a[ i] - a[ i - 1 ] ;
add ( tr1, i, b) ;
add ( tr2, i, ( LL) b * i) ;
}
while ( m -- )
{
char op[ 2 ] ;
int l, r, d;
scanf ( "%s%d%d" , op, & l, & r) ;
if ( * op == 'Q' )
{
printf ( "%lld\n" , prefix_sum ( r) - prefix_sum ( l - 1 ) ) ;
}
else
{
scanf ( "%d" , & d) ;
add ( tr1, l, d) , add ( tr2, l, l * d) ;
add ( tr1, r + 1 , - d) , add ( tr2, r + 1 , ( r + 1 ) * - d) ;
}
}
return 0 ;
}
懒标签——线段树做法
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010 ;
int n, m;
int w[ N] ;
struct Node
{
int l, r;
LL sum, add;
} tr[ N * 4 ] ;
void pushup ( int u) {
tr[ u] . sum = tr[ u << 1 ] . sum + tr[ u << 1 | 1 ] . sum;
}
void pushdown ( int u) {
int left= u<< 1 ; int right= u<< 1 | 1 ;
if ( tr[ u] . add) {
tr[ left] . add+ = tr[ u] . add; tr[ left] . sum+ = ( LL) ( tr[ left] . r- tr[ left] . l+ 1 ) * ( tr[ u] . add) ;
tr[ right] . add+ = tr[ u] . add; tr[ right] . sum+ = ( LL) ( tr[ right] . r- tr[ right] . l+ 1 ) * ( tr[ u] . add) ;
tr[ u] . add= 0 ;
}
}
void build ( int u, int l, int r) {
if ( l== r) tr[ u] = { l, r, w[ l] , 0 } ;
else {
tr[ u] = { l, r} ;
int mid= l+ r>> 1 ;
build ( u << 1 , l, mid) , build ( u << 1 | 1 , mid + 1 , r) ;
pushup ( u) ;
}
}
void modify ( int u, int l, int r, int d) {
if ( tr[ u] . l>= l&& tr[ u] . r<= r) {
tr[ u] . sum + = ( LL) ( tr[ u] . r - tr[ u] . l + 1 ) * d;
tr[ u] . add + = d;
}
else {
pushdown ( u) ;
int mid= tr[ u] . l+ tr[ u] . r>> 1 ;
if ( l<= mid) modify ( u<< 1 , l, r, d) ;
if ( r> mid) modify ( u<< 1 | 1 , l, r, d) ;
pushup ( u) ;
}
}
LL query ( int u, int l, int r) {
if ( tr[ u] . l>= l&& tr[ u] . r<= r) return tr[ u] . sum;
else {
pushdown ( u) ;
int mid = tr[ u] . l + tr[ u] . r >> 1 ;
LL sum = 0 ;
if ( l <= mid) sum = query ( u << 1 , l, r) ;
if ( r > mid) sum + = query ( u << 1 | 1 , l, r) ;
pushup ( u) ;
return sum;
}
}
int main ( ) {
cin >> n >> m;
for ( int i= 1 ; i<= n; i++ ) cin >> w[ i] ;
build ( 1 , 1 , n) ;
char op[ 2 ] ;
int l, r, d;
while ( m -- )
{
scanf ( "%s%d%d" , op, & l, & r) ;
if ( * op == 'C' )
{
scanf ( "%d" , & d) ;
modify ( 1 , l, r, d) ;
}
else printf ( "%lld\n" , query ( 1 , l, r) ) ;
}
return
}