树状数组(3)

来源:互联网 发布:手机ai软件下载 编辑:程序博客网 时间:2024/06/11 14:45

这一篇来讲一些比较务实的东西

之前说过,树状数组能做的东西线段树都能做
代码这么简单的树状数组能不能做线段树经常要做的改点(段)求段(点)呢?
废话,这么简单的东西答案当然是能啦

1、改点求段(codevs 1080)

算法简单代码简单不解释了
代码:

#include <cstdio>#include <cstring>using namespace std;int c[100010],l[100010],n;int lowbit(int x){    return x&-x;}void add(int x,int y){    while (x<=100000)    {        c[x]+=y;        x+=lowbit(x);    }}int getsum(int x){    int s=0;    while (x>=1)    {        s+=c[x];        x-=lowbit(x);    }    return s;}int main(){    int n,x,y,z,u,m;    scanf("%d",&n);    for (int i=1;i<=n;i++)    {        scanf("%d",&u);        add(i,u);    }    scanf("%d",&m);    for (int i=1;i<=m;i++)    {        scanf("%d",&u);        if (u==1)         {            scanf("%d%d",&x,&z);            add(x,z);        }        else         {            scanf("%d%d",&x,&y);            printf("%d\n",getsum(y)-getsum(x-1));            //[x~y]=[1~Y]-[1~X-1];        }    }    return 0;}

2、该段求点(codevs1081 )

#include <cstdio>#include <cstring>using namespace std;int c[100010],l[100010],n;int lowbit(int x){    return x&-x;}void add(int x,int y){    while (x<=100000)    {        c[x]+=y;        x+=lowbit(x);    }}int getsum(int x){    int s=0;    while (x>=1)    {        s+=c[x];        x-=lowbit(x);    }    return s;}int main(){    int n,x,y,z,u,m;    scanf("%d",&n);    for (int i=1;i<=n;i++)    {        scanf("%d",&u);        add(i,u);//[i~n]都加z        add(i+1,-u);//只更改i这个点,所以[i+1,n]以后的点要还原    }    scanf("%d",&m);    for (int i=1;i<=m;i++)    {        scanf("%d",&u);        if (u==1)         {            scanf("%d%d%d",&x,&y,&z);            add(x,z);//[x~n]的点都加z            add(y+1,-z);//因为只是更改[x~y]的点,所以[y+1~n]要还原        }        else         {            scanf("%d",&x);            printf("%d\n",getsum(x));        }    }    return 0;}

3、该段求段(codevs 1082)

#include<iostream>#include<cstdio>#include<cstring>#define N 200009using namespace std;int n,m;long long c[2][N];int lowbit(int x) {    return x&-x;}void add(int x,long long y,int opp){    while(x<=n)    {        c[opp][x]+=y;        x+=lowbit(x);    }}long long getsum(int x,int opp){    long long s=0;    while(x>=1)    {        s+=c[opp][x];        x-=lowbit(x);    }    return s;}long long ans(int x)//ASK:ans=X.sum(k)*k+Y.sum(k){    return (x+1)*getsum(x,0)+getsum(x,1);}int main(){    int i,j,k,x,y,opp;    long long z;    scanf("%d",&n);    for (i=1;i<=n;i++)    {        scanf("%d",&x);        add(i,x,0),add(i+1,-x,0);        add(i,-x*i,1),add(i+1,x*(i+1),1);    }    int m;scanf("%d",&m);     while(m--)    {        scanf("%d%d%d",&opp,&x,&y);        if(opp==1)        {            scanf("%lld",&z);            /*            CHANGE:            X[L]+=val,X[R+1]-=val            Y[L]+=-val*(L-1),Y[R+1]+=val*R;            */            add(x,z,0),add(y+1,-z,0);            add(x,-x*z,1),add(y+1,(y+1)*z,1);        }        else printf("%lld\n",ans(y)-ans(x-1));    }}
0 0