树状数组 线段树 区间修改区间查询

树状数组

该方法详情见 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 }

猜你喜欢

转载自www.cnblogs.com/GC-hahaha/p/9458582.html