博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
树状数组
阅读量:5229 次
发布时间:2019-06-14

本文共 3048 字,大约阅读时间需要 10 分钟。

树状数组的基础知识点 

树状数组的基础操作

  1.单点更新,区间查询

 

int lowbit(int x){    return x&(-x);}int sum(int x){    int ans=0;    for(int i=x;i>0;i-=lowbit(i)){        ans+=a[i];    }    return ans;}void updata(int x,int y){    for(int i=x;i<=n;i+=lowbit(i)){        a[i]+=y;    }}void solve(){    updata(x,y);    printf("%d\n",sum(y)-sum(x-1));1-1,y1-1));}

 

 

 

  2,区间更新,单点查询

   了解差分:

      通过“差分”(就是记录数组中每个元素与前一个元素的差,如果求第i的值是多少 那么就是把差分数组从1,2,3......i相加 就是第i个的值),所以可以把这个问         

 

int lowbit(int x){    return x&(-x);}void updata(int x,int y){    for(int i=x;i<=n;i+=lowbit(i)){        s[i]+=y;    }}int sum(int x){    int ans=0;    for(int i=x;i>0;i-=lowbit(i)){        ans+=s[i];    }    return ans;}void solve(){    updata(a,1);    updata(b+1,-1);    printf("%d\n",sum(y));}

  3,区间更新,区间查询

  

int lowbit(int x){    return x&(-x);}void updata(int p,long long x){    for(int i=p;i<=n;i+=lowbit(i)){        s1[i]+=x;        s2[i]+=x*p;    }}long long sum(int p){    long long ans=0;    for(int i=p;i>0;i-=lowbit(i)){        ans+=s1[i]*(p+1)-s2[i];    }    return ans;}void solve(){    updata(a,1);    updata(b+1,-1);    printf("%d\n",sum(y)-sum(x-1));}

  4:二维树状数组

          单点更新  区间查询

我们已  经学会了对于序列的常用操作,那么我们不由得想到…… 能不能把类似的操作应用到矩阵上呢?这时候我们就要写二维树状数组了!

在一维  树状数组中,tree[x](树状数组中的那个“数组”)记录的是右端点为x、长度为lowbit(x)的区间的区间和。

那么在  二维树状数组中,可以类似地定义tree[x][y]记录的是右下角为(x, y),高为lowbit(x), 宽为 lowbit(y)的区间的区间和。

int lowbit(int x){    return x&(-x);}void updata(int x,int y,int z){    for(int i=x;i<=n;i+=lowbit(i)){        for(int j=y;j<=m;j+=lowbit(j)){            s[i][j]+=z;        }    }}long long sum(int x,int y){    long long res=0;    for(int i=x;i>0;i-=lowbit(i)){        for(int j=y;j>0;j-=lowbit(j)){            res+=s[i][j];        }    }    return res;}void solve(){    updata(x,y,z);    //这个是求面积的公式 画图会比较好理解    printf("%lld\n",sum(x2,y2)+sum(x1-1,y1-1)-sum(x1-1,y2)-sum(x2,y1-1));}

      区间更新 单点查询

int lowbit(int x){    return x&(-x);}void updata(int x,int y,int z){    for(int i=x;i<=n;i+=lowbit(i)){        for(int j=y;j<=n;j+=lowbit(j)){            s[i][j]+=z;        }    }}int sum(int x,int y){    int res=0;    for(int i=x;i>0;i-=lowbit(i)){        for(int j=y;j>0;j-=lowbit(j)){            res+=s[i][j];        }    }    return res;}void solve(){    updata(x1,y1,1);    updata(x2+1,y1,-1);    updata(x1,y2+1,-1);    updata(x2+1,y2+1,1);    printf("%d\n",sum(x,y));}

 

区间更新 区间查询

int lowbit(int x){    return x&(-x);}void updata(int x,int y,long long z){    for(int i=x;i<=n;i+=lowbit(i)){        for(int j=y;j<=n;j+=lowbit(j)){            s1[i][j]+=z;            s2[i][j]+=x*z;            s3[i][j]+=y*z;            s4[i][j]+=x*y*z;        }    }}long long sum(int x,int y){    long long res=0;    for(int i=x;i>0;i-=lowbit(i)){        for(int j=y;j>0;j-=lowbit(j)){            res+=(x+1)*(y+1)*s1[i][j]-(y+1)*s2[i][j]-(x+1)*s3[i][j]+s4[i][j];        }    }    return res;}void solve(){    updata(x1,y1,1);    updata(x2+1,y1,-1);    updata(x1,y2+1,-1);    updata(x2+1,y2+1,1);    printf("%lld\n",sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1));}

 

转载于:https://www.cnblogs.com/chenchen-12/p/10189151.html

你可能感兴趣的文章
react 添加less支持
查看>>
在iPhone应用中使用自定义字体
查看>>
jquery解决onmouseover和onmouseout合用的bug问题
查看>>
ORACLE的工作机制
查看>>
动态查询与查询分析器的查找替换
查看>>
Android SDCard UnMounted 流程分析(一)
查看>>
ApexSQL Recover 恢复一个被drop的表的数据
查看>>
Dataset
查看>>
SCSS 在项目中的运用
查看>>
bcrypt 安装不成功解决办法
查看>>
[转] Linux常用命令大全(非常全!!!)
查看>>
C++ 使用vector时遇到的一个问题
查看>>
解决Ubuntu18.10 网络图标经常消失连不上网问题
查看>>
每天CookBook之Python-101
查看>>
Android的底层库libutils介绍
查看>>
mysql服务器参数
查看>>
【webpack】流行的前端模块化工具webpack初探
查看>>
变量名与函数名的命名规范
查看>>
hdu 2066 一个人的旅行
查看>>
经理评分
查看>>