个人觉得树状数组十分好用,虽然功能十分简单,但却可以用来优化其他题中的查询与修改...

比较好的博客

数据结构就没学多少,就学好这个吧!

单点修改与区间查询:

#include<bits/stdc++.h>
using namespace std;
const int N=501000;
int n,m,a[N],c[N];
inline int read()
{
    int x=0,ff=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
    while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*ff;
}
inline int lowbit(int x) {return x&(-x);}
inline void add(int x,int k)
{
    for(;x<=n;x+=lowbit(x)) c[x]+=k;
}
inline int ask(int x)
{
    int ans=0;
    for(;x>0;x-=lowbit(x)) ans+=c[x];
    return ans;
}
int main()
{
    //freopen("1.in","r",stdin);
    n=read();m=read();
    for(register int i=1;i<=n;++i) a[i]=read(),add(i,a[i]);
    for(register int i=1;i<=m;++i)
    {
        int p=read(),x=read(),y=read();
        if(p==1) add(x,y);
        else if(p==2) printf("%d\n",ask(y)-ask(x-1));
    }
    return 0;
}

区间修改与单点查询:

#include<bits/stdc++.h>
using namespace std;
const int N=501000;
int n,m,a[N],c[N];
inline int read()
{
    int x=0,ff=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
    while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*ff;
}
inline int lowbit(int x){return x&(-x);}
inline void add(int x,int k)
{
    for(;x<=n;x+=lowbit(x)) c[x]+=k;
}
inline int ask(int x)
{
    int ans=0;
    for(;x>0;x-=lowbit(x)) ans+=c[x];
    return ans;
}
int main()
{
//    freopen("1.in","r",stdin);
    n=read();m=read();
    for(register int i=1;i<=n;++i) a[i]=read(),add(i,a[i]-a[i-1]);
    for(register int i=1;i<=m;++i)
    {
        int p=read();
        if(p==1)
        {
            int x=read(),y=read(),k=read();
            add(x,k);add(y+1,-k);
        }
        else if(p==2)
        {
            int x=read();
            printf("%d\n",ask(x));
        }
    }
    return 0;
}
02-12 20:02