树状数组的两种运用

来源:互联网 发布:推荐les淘宝店 编辑:程序博客网 时间:2024/05/29 14:27

运用1

单点修改,区间查询。

add(pos,x)->在下标 pos 处加上 x
query(pos)->返回 1 到 pos 的前缀和

那么查询区间 [ l , r ]的操作就是query( r ) - query( l - 1 )

例题——洛谷3374

代码

#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<cmath>using namespace std;const int maxn=500000+10;int a[maxn];int n,m;inline int lowbit(int x){    return x&(-x);}inline void add(int pos,int val){    while(pos<=n){        a[pos]+=val;        pos+=lowbit(pos);    }}inline int query(int pos){    int res=0;    while(pos>0){        res+=a[pos];        pos-=lowbit(pos);    }    return res;}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++){        int x;        scanf("%d",&x);        add(i,x);//赋初值     }    for(int i=1;i<=m;i++){        int op;        scanf("%d",&op);        if(op==1){            int x,y;            scanf("%d%d",&x,&y);            add(x,y);        }        if(op==2){            int x,y;            scanf("%d%d",&x,&y);            printf("%d\n",query(y)-query(x-1));        }    }    return 0;}

运用二

区间修改,单点查询

add 和 query 的操作同运用一,但是使用方式不同:
区间修改(给区间 [ l , r ]加上 d)->

add(l,d);add(r+1,-d);

单点查询(查询 pos 的值)->

query(pos);

例题——洛谷3368

代码

#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<cmath>using namespace std;const int maxn=500000+10;int c[maxn]; int n;inline int lowbit(int x){    return x&(-x);}inline void add(int pos,int val){    while(pos<=n){        c[pos]+=val;        pos+=lowbit(pos);    }}inline int query(int pos){    int res=0;    while(pos>0){        res+=c[pos];        pos-=lowbit(pos);    }    return res;}int main(){    int m;    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++){        int x;        scanf("%d",&x);        add(i,x);        add(i+1,-x);    }    for(int i=1;i<=m;i++){        int op;        scanf("%d",&op);        if(op==1){            int x,y,z;            scanf("%d%d%d",&x,&y,&z);            add(x,z);            add(y+1,-z);        }        if(op==2){            int x;            scanf("%d",&x);            printf("%d\n",query(x));        }    }    return 0;}

后记

  1. 两种运用的add 和 query 完全一样。
  2. 至于为什么,感觉不好解释,大概是差分的思想,现场手推一下即可。

挖个坑

据说还有一种区间修改区间查询的,过会儿再写。

0 0
原创粉丝点击