【模板】树状数组2

Posted on 2018-08-12 11:16  亦辰落  阅读(240)  评论(0编辑  收藏  举报

此题为洛谷P3368

传送门

有些一些是转载于此:

https://www.cnblogs.com/hsd-/p/6139376.html

顺带总结一下最近学的树状数组(笑)

#include<bits/stdc++.h>
using namespace std;
int n,m;
long long a[50000005];
int lowbit(int x){
    return x&(-x);//-t 代表t的负数 计算机中负数使用对应的正数的补码来表示
}//印象中是树状数组最主要的结构!!!
//lowbit(x) 其实就是取出x的最低位1 
void add(long long p,long long x){
    while(p<=n)
    {
        a[p]+=x;
        p+=lowbit(p);
    }//可以发现 更新过程是查询过程的逆过程
    //由叶子结点向上更新C[]数组
}
int find(long long p){
    long long ans=0;
    while(p>0)
    {
        ans+=a[p];
        p-=lowbit(p);
    }//利用C[i]数组,求A数组中前i项的和
    return ans;
}
int main(){
    scanf("%d%d",&n,&m);
    long long last = 0, now;
    for (int i = 1; i <= n; i++) {
        scanf("%lld", &now);
        add(i, now - last);
        last = now;
    }
    int f;
    while (m--) {
        scanf("%d", &f);
        if (f == 1) {
            int x, y;
            long long k;
            scanf("%d%d%lld", &x, &y, &k);
            add(x, k);
            add(y + 1, -k);
        } else if (f==2) {
            int t;
            scanf("%d", &t);
            printf("%lld\n", find(t));
        }
    }
    return 0;
}

作为小juluo的我竟然自己总结(假的)

希望对每个和我一样的juluo又一点想法,嘻嘻!!!

洛谷里好像还有一题,

P3374 传送门

题解:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,tree[2000010];
int lowbit(int x){
    return x&(-x);
}
void add(int x,int k){
    for(int i=x;i<=n;i+=lowbit(i))tree[i]+=k;
}
int find(int x){
    int sum=0;
    for(int i=x;i;i-=lowbit(i))sum+=tree[i];
    return sum;
}
int main(){    
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int a;
        cin>>a;
        add(i,a);    
    }
    for(int i=1;i<=m;i++){
        int a,b,c;
        cin>>a>>b>>c;
        if(a==1)add(b,c);
        else cout<<find(c)-find(b-1)<<endl;
    }
    return 0;
}

总结一下

其实在树状数组中lowbit函数是最关键的,

因为它操纵了整个树状数组(笑)