树状数组(BIT)

单点修改,区间查询

可以实现基本操作:

1、给定 i ,x . 给 bit[i] 加上 x

2、给定 l , r . 求出 bit[l] +...+ bit[r] 

 

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxn = 1e6 + 10;
#define int long long
int bit[maxn];
int n, q;
int lowbit(int i){
    return i&(-i);
}
long long getsum(int i){   //bit[1]+...+bit[i]  前缀和
    long long res = 0;
    while (i >0 ){
        res += bit[i];
        i -= lowbit(i);
    }
    return res;
}
void add(int i, int x){    //在bit[i]上加上x
    while (i <=n){
        bit[i] += x;
        i += lowbit(i);
    }
}
int main()
{
    cin >> n >> q;    //n和数,q次查询
    int z;
    for (int i = 1; i <= n; i++){
        cin >> z;
        add(i,z);
    }
    int a,b,c;
    while (q--){
        
        cin >> a >> b >> c;
        if (a == 1){
            add(b,c);
        }
        else if(a == 2){
            cout << getsum(c)-getsum(b-1) << endl;
        }
    }
    return 0;
}
View Code

区间修改,单点查询

 

1、给定 x y k ,使的 bit[x]...bit[y] 加上k

2、给定 i ,求 bit[i]

 

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxn = 1e6 + 10;
#define int long long
int bit[maxn];
int n, q;
int lowbit(int i){
    return i&(-i);
}
long long query(int i){   
    long long res = 0;
    while (i >0 ){
        res += bit[i];
        i -= lowbit(i);
    }
    return res;
}
void add(int i, int x){    
    while (i <=n){
        bit[i] += x;
        i += lowbit(i);
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin >> n >> q;    //n和数,q次查询
    int z,x=0;
    for (int i = 1; i <= n; i++){
        cin >> z;
        add(i,z-x);
        x = z;
    }
    int a,b,c,d;
    while (q--){
        
        cin >> a;
        if (a == 1){
            cin >> b >> c>>d;
            add(b,d);
            add(c+1,-d);
        }
        else if(a == 2){
            cin >> b;
            cout << query(b) << endl;
        }
    }
    return 0;
}
View Code

区间修改,区间查询

  • 1 l r x:对于所有 i∈[l,r],将a[i]加上 x
  • 2 l r:输出 a[l]+...+a[l] 的值
#include<iostream>
using namespace std;
const int maxn = 1e6+10;
typedef long long ll;
#define int long long
//========================
ll bit[maxn][2];  //bit[i][0] 维护(di)差分,bit[i][1]维护(di)*i 
int n,q;
//========================
int lowbit(int i){
    return i&(-i);
}
void update(int i,ll x,int flag){
    while (i <= n){
        bit[i][flag] += x;
        i += lowbit(i);
    }
}
ll query(int i,int flag){
    ll res = 0;
    while (i > 0){
        res += bit[i][flag];
        i -= lowbit(i);
    }
    return res;
}
ll ask(int i){
    return  (i + 1)*query(i, 0) - query(i, 1);
}
signed main()
{
    ios::sync_with_stdio(false);
    cin >> n >> q;
    int b,a=0;
    for (int i = 1; i <= n; i++){
        cin >> b;
        update(i,b-a,0);
        update(i,(b-a)*i,1);
        a = b;
    }
    int op;
    int l, r;
    ll x;
    while (q--){
        cin >> op;
        if (op == 1){
            cin >> l >> r >> x;
            update(l,x,0);
            update(r+1,-x,0);
            update(l,x*l,1);
            update(r+1,-x*(r+1),1);
        }
        else {
            cin >> l >> r;
            cout << ask(r) - ask(l - 1) << endl;
        }
    }
    return 0;
}
View Code

 

posted @ 2019-03-05 19:31  looeyWei  阅读(276)  评论(0)    收藏  举报