树状数组

 单点修改&区间查询

#include<iostream>
#include<cstdio>
#include<cstdlib>
#define maxn 500010
using namespace std;
template<typename T>
inline void read(T &x){
    x=0; bool flag=0; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
    for(;isdigit(c);c=getchar()) x=x*10+(c^48);
    if(flag) x=-x;
}

int n,m,num,x,y,k;
int a[maxn],b[maxn];

void add(int x,int y){
    for(;x<=n;x+=x&-x) b[x]+=y;
}

int ask(int x){
    int ans=0;
    for(;x;x-=x&-x) ans+=b[x];
    return ans;
}

int main(){
    read(n),read(m);
    for(int i=1;i<=n;i++){
        read(a[i]);
        add(i,a[i]);
    }
    for(int i=1;i<=m;i++){
        read(num);
        if(num==1){
            read(x),read(k);
            add(x,k);
        }
        if(num==2){
            read(x),read(y);
            cout<<ask(y)-ask(x-1)<<endl;
        }
    }
    return 0;
}

区间修改&单点查询

#include<iostream>
#include<cstdio>
#include<cstdlib>
#define maxn 500010
using namespace std;
template<typename T>
inline void read(T &x){
    x=0; bool flag=0; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
    for(;isdigit(c);c=getchar()) x=x*10+(c^48);
    if(flag) x=-x;
}

int n,m,num,x,y,k,temp=0;
int a[maxn],b[maxn]; 

void add(int x,int y){
    for(;x<=n;x+=x&-x) b[x]+=y;//lowbit
}

int ask(int x){
    int ans=0;
    for(;x;x-=x&-x) ans+=b[x];//lowbit 
    return ans;
}

int main(){
    read(n),read(m);
    for(int i=1;i<=n;i++) {
        read(a[i]);
        add(i,a[i]-temp);
        temp=a[i];
    }
    for(int i=1;i<=m;i++){
        read(num);
        if(num==1){
            read(x),read(y),read(k);
            add(x,k);//差分思想 
            add(y+1,-k);//对区间[x,y]修改,只要修改b[x]和b[y+1]即可 
        }
        if(num==2){
            read(x);
            cout<<ask(x)<<endl;
        }
    }
    return 0;
} 

 

posted @ 2021-02-14 22:48  DReamLion  阅读(22)  评论(0编辑  收藏  举报