前缀和/树状数组(一维+二维)/差分

1.前缀和

一维:就是数组y是数组x前面所有数字的和
在这里插入图片描述

2.树状数组(一维)

前缀和在更新的时候,对应的数字都要更新,十分复杂,所以引入树状数组。还是之前那个数组,只不过元素之间的逻辑关系不是直线,而是树的样子
在这里插入图片描述
特点:
c的项数 == 数字二进制最低位1所代表的数字
在这里插入图片描述

// 求最低位1方法

int lowbit(x)   //简单写法,还有一种复杂一点的,不管~
{
	return x & -x ;
}

更新操作

在这里插入图片描述

查询操作

在这里插入图片描述

题目

1.敌兵布阵
2.交换的次数
3.星星Stars

3.树状数组(二维)

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

设原始二维数组为:

A[][]={
{a11,a12,a13,a14,a15,a16,a17,a18},
{a21,a22,a23,a24,a25,a26,a27,a28},
{a31,a32,a33,a34,a35,a36,a37,a38},
};

先对每一行,用树状数组建立

第一行:B[1]={a11, a11+a12, a13, a11+a12+a13+a14, a15, a15+a16,…}
第二行:B[2]={a21, a21+a22,a23, a21+a22+a23+a24, a25, a25+a26,…}
第三行:B[3]={a31, a31+a32, a33, a31+a32+a33+a34, a35, a35+a36,…}
第四行:B[4]={a41, a41+a42, a43, a41+a42+a43+a44, a45, a45+a46,…}

再对每一列,用树状数组建立

第一行二维树状数组 == 第一行
C[1][1]=a11,C[1][2]=a11+a12,C[1][3]=a13,C[1][4]=a11+a12+a13+a14,c[1][5]=a15,C[1][6]=a15+a16,…

第二行二维树状数组 == 第一行+第二行
C[2][1]=a11+a21,C[2][2]=a11+a12+a21+a22,C[2][3]=a13+a23,C[2][4]=a11+a12+a13+a14+a21+a22+a23+a24,
C[2][5]=a15+a25,C[2][6]=a15+a16+a25+a26,…

第三行二维树状数组 == 第三行
C[3][1]=a31,C[3][2]=a31+a32,C[3][3]=a33,C[3][4]=a31+a32+a33+a34,C[3][5]=a35,C[3][6]=a35+a36,…

第四行二维树状数组 == 第一行+第二行+第三行+第四行
C[4][1]=a11+a21+a31+a41,C[4][2]=a11+a12+a21+a22+a31+a32+a41+a42,C[4][3]=a13+a23+a33+a43,…

int lowbit(int x)
{
    return x & (-x);
}

void update(int x, int y, int a)
{
    for(int i=x;i<=s;i+=lowbit(i))
        for(int j=y;j<=s;j+=lowbit(j))
            map[i][j]+=a;
}

int add(int x, int y)  //从(1,1)到(x,y)
{
    int sum=0;
    for(int i=x;i>0;i-=lowbit(i))
        for(int j=y;j>0;j-=lowbit(j))
            sum+=map[i][j];
    return sum;

}

题目

1.模板题

4.差分

数组中记录的是每个元素与上一个元素的差值
利用前缀和实现单点查询
当区间修改的时候,给区间 [ l , r ] [l,r] [l,r]加上k时,a[l]比a[l-1]多了k,a[r]比a[r+1]少了k,只需要操作两端的值即可

题目

1.color the ball
2.Covered Points Count /像但不是

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值