您的位置:首页 > 其它

树状数组 总结

2017-10-16 17:29 375 查看
我看到的讲的最仔细的最棒的一个树状数组讲解。
http://www.cnblogs.com/hsd-/p/6139376.html
直接看这个链接即可。

单点更新,区间查询

#include<iostream>

#include<cstring>

#include<cstdio>

#include<cstdlib>

using namespace std;

int n,m;

int c[500005];

int lowbit(int x)

{

    return (-x)&x;

}

void add(int pos,int x)

{

    while(pos<=n)

    {

        c[pos]+=x;

        pos+=lowbit(pos);

    }

}

void input()

{

    int x;

    for(int i=1;i<=n;i++)

    {

        scanf("%d",&x);

        add(i,x);

    }

}

int query(int pos)

{

    int res=0;

    while(pos>0)

    {

        res+=c[pos];

        pos-=lowbit(pos);

    }

    return res;

}

int main()

{

    scanf("%d%d",&n,&m);

    input();

    int f,x,y;

    for(int i=1;i<=m;i++)

    {

        scanf("%d%d%d",&f,&x,&y);

        if(f==1)

        add(x,y);

        else if(f==2) 

        cout<<query(y)-query(x-1)<<endl;               //主要是注意这里。 y和x-1

    }

    return 0;

}

区间修改 单点查询

#include<iostream>

#include<cstring>

#include<queue>

#include<cstdio>

using namespace std;

int c[500005];

int n,m;

int lowbit(int x)

{

    return x&(-x);

}

void add(int pos,int x)

{

    while(pos<=n)

    {

        c[pos]+=x;

        pos+=lowbit(pos);

    }

}

int query(int pos)

{

    int res=0;

    while(pos>0)

    {

        res+=c[pos];

        pos-=lowbit(pos);

    }

    return res;

 } 

int main()

{

    scanf("%d%d",&n,&m);

    int x=0,y;

    for(int i=1;i<=n;i++)

    {

        scanf("%d",&y);

        add(i,y-x);

        x=y;

    }

    int opt,k;

    for(int i=1;i<=m;i++)

    {

        scanf("%d",&opt);

        if(opt==1)

        {

            scanf("%d%d%d",&x,&y,&k);

            add(x,k);                    //注意这两部分。其实可以理解成x到1加k,之后y到1减k。把1

            add(y+1,-k);                 //到x给抵消掉了,只剩下了x到y。   可能有人会感觉+k和-k是不是

                                         //写反了,其实我们这里可以理解成,只是理解是x到1,y到1。而不是

                                        //1到x,1到y。想一下那个图。 

        }

        else if(opt==2)

        {

            scanf("%d",&x);

            printf("%d\n",query(x));

        }

    }

    return 0;

 } 

区间修改 区间查询

#include<iostream>

#include<cstring>

#include<cstdio>

using namespace std;

long long c[200005][2];

int n,q;

int lowbit(int x)

{

    return x&(-x);

}

void add(int pos,int x,int f)

{

    while(pos<=n)

    {

        c[pos][f]+=x;

        pos+=lowbit(pos);

    }

}

long long query(int pos,int f)

{

    long long res=0;

    while(pos>0)

    {

        res+=c[pos][f];

        pos-=lowbit(pos);

    }

    return res;

 }

long long ask(int pos)

{

    long long res=(pos+1)*query(pos,0)-query(pos,1);

    return res; 

}

int main()

{

    scanf("%d",&n);

    int a=0,b,opt,x;

    for(int i=1;i<=n;i++)

    {

        scanf("%d",&b);

        add(i,b-a,0);

        add(i,(b-a)*i,1);

        a=b;

    }

    scanf("%d",&q);

    for(int i=1;i<=q;i++)

    {

        scanf("%d",&opt);

        if(opt==1)

        {

            scanf("%d%d%d",&a,&b,&x);

            add(a,x,0);

            add(b+1,-x,0);

            add(a,x*a,1);

            add(b+1,-x*(b+1),1);

        }

        else if(opt==2)

        {

            scanf("%d%d",&a,&b);

            printf("%lld\n",ask(b)-ask(a-1));

        }

    }

    return 0;

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: