树状数组
该方法详情见 https://www.cnblogs.com/RabbitHu/p/BIT.html 写的超级好!
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll ; 4 const int MAX = 1e7 + 3 ; 5 ll n , m , k , x , y , s ; 6 ll a[MAX] , sum1[MAX] , sum2[MAX] , c[MAX] ; 7 8 inline int get(){ 9 char c ; 10 int sign = 1 ; 11 while((c = getchar())<'0' || c >'9') 12 if(c == '-') sign = -1 ; 13 int res = c - '0' ; 14 while ((c = getchar()) >= '0' && c <= '9') 15 res = res * 10 + c - '0' ; 16 return res * sign ; 17 } 18 19 inline ll lowbit(ll x){ 20 return x & -x; 21 } 22 23 ll find(ll x ){ 24 ll ans = 0 ; 25 for(int i = x ; i!=0 ; i -= lowbit(i) ) ans += sum1[i] * (x + 1) - sum2[i] ; 26 return ans ; 27 } 28 29 void add( ll x , ll y){ 30 for(int i = x ; i <= n ; i += lowbit(i) ) sum1[i] += y , sum2[i] += y * x ; 31 } 32 33 void add_zone( ll x , ll y , ll z ){ 34 add( x , z ); 35 add( y + 1 , - z ); 36 } 37 38 int main(){ 39 //freopen("data.in","r",stdin); 40 //freopen("data.out","w",stdout); 41 n = get() , m = get() ; 42 for(ll i = 1 ; i <= n ; ++ i){ 43 a[i] = get() ; 44 c[i] = a[i] - a[i - 1]; 45 for(ll j = 1 ; j <= lowbit(i) ; ++ j){ 46 sum1[i] += c[i - j + 1]; 47 sum2[i] += c[i - j + 1] * (i - j + 1) ; 48 } 49 } 50 for(ll i = 1 ; i <= m ; ++ i){ 51 k = get() , x = get() , y = get() ; 52 if(k == 2){ 53 cout << find(y) - find(x - 1) << endl; 54 } 55 else{ 56 s = get() ; 57 add_zone( x , y , s ); 58 } 59 } 60 return 0 ; 61 }
线段树
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll ; 4 const int MAX = 1e6 + 5 ; 5 ll x , y , z , n , m , u , e ; 6 ll a[MAX] , tree[MAX * 4] , lazy[MAX * 4] ; 7 8 inline int get(){ 9 char c ; 10 int sign = 1 ; 11 while((c = getchar())<'0' || c >'9') 12 if(c == '-') sign = -1 ; 13 int res = c - '0' ; 14 while ((c = getchar()) >= '0' && c <= '9') 15 res = res * 10 + c - '0' ; 16 return res * sign ; 17 } 18 19 void build( ll x , ll y , ll z ){ 20 if(y == z){ 21 tree[x] = a[y] ; 22 return ; 23 } 24 ll mid = (y + z) >> 1 ; 25 build( x<<1 , y , mid ); 26 build( (x<<1) + 1 , mid + 1 , z ); 27 tree[x] = tree[x<<1] + tree[(x<<1) + 1]; 28 } 29 30 /*void single_add(int x , int y , int z , int p , int q){ 31 if(y > p || z < p) { 32 return ; 33 } 34 if(y == z){ 35 36 tree[x] += q ; 37 return ; 38 } 39 int mid = (y + z) >> 1 ; 40 single_add(x*2 , y , mid , p , q); 41 single_add(x*2 + 1 , mid + 1 , z , p , q); 42 43 tree[x] = tree[x*2] + tree[x * 2 + 1] ; 44 }*/ 45 46 void add(ll x , ll y , ll z , ll p){ 47 lazy[x] += p ; 48 tree[x] += p * (z - y + 1) ; 49 } 50 51 void download(ll x , ll y , ll z , ll p){ 52 if(!lazy[x]) return ; 53 add(x<<1 , y , p , lazy[x]); 54 add((x<<1)+ 1 , p + 1 , z , lazy[x]); 55 lazy[x] = 0 ; 56 } 57 58 void zone_add(ll x , ll y , ll z , ll p , ll q , ll e){ 59 if(y > q || z < p) return ; 60 if(y >= p && z <= q){ 61 add(x , y , z , e); 62 return ; 63 } 64 ll mid = (y + z) >> 1 ; 65 download(x , y , z , mid); 66 if(p <= mid) zone_add(x<<1 , y , mid , p , q , e) ; 67 if(q > mid) zone_add((x<<1) + 1 , mid + 1 , z , p , q , e) ; 68 tree[x] = tree[x<<1] + tree[(x<<1) + 1]; 69 } 70 71 ll zone_sum(ll x , ll y , ll z , ll p , ll q){ 72 if(y > q || z < p ) return 0; 73 if(y >= p && z <= q){ 74 return tree[x]; 75 } 76 ll mid = (y + z) >> 1 ; 77 ll ans = 0 ; 78 download(x , y , z , mid); 79 if( p <= mid ) ans += zone_sum(x<<1 , y , mid , p , q); 80 if( q > mid) ans+= zone_sum((x<<1) + 1 , mid + 1 , z , p , q); 81 return ans ; 82 } 83 84 int main(){ 85 //freopen("data.in","r",stdin); 86 //freopen("data.out","w",stdout); 87 n = get() , m = get() ; 88 for(int i = 1 ; i <= n ; ++ i){ 89 a[i] = get() ; 90 } 91 build ( 1 , 1 , n ) ; 92 for(int i = 1 ; i <= m ; ++ i){ 93 x = get() , y = get() , z = get() ; 94 if(x == 1){ 95 e = get() ; 96 zone_add( 1 , 1 , n , y , z , e ) ; 97 } 98 else if(x == 2){ 99 printf("%lld\n" , zone_sum( 1 , 1 , n , y , z ) ); 100 } 101 } 102 return 0 ; 103 }