树状数组学习(例题及题解)

本文介绍了树状数组的概念及其在动态维护前缀和中的应用。通过代码模板展示了如何实现添加元素和查询前缀和的操作,并提供了两个实际问题的解题思路:一是楼兰图腾问题,利用树状数组计算特定位置的乘积;二是整数问题,结合差分数组进行动态更新。这些例子展示了树状数组在解决数学和数组操作问题上的高效性。

在这里插入图片描述
树状数组:可以动态维护前缀和,查询时间复杂度O(log2n),修改时间复杂度O(log2n)。
树状数组记录前缀和的方式为这个数的二进制表示中从长度是从右往左的第一个0的大小,即长度为x-lowbit(x)+1。
代码模板

int tr[N];
int lowbit(int x)   //求第一个0的位置
{
    return x & -x;
}

void add(int x, int c) 在位置为x的地方加上c
{
    for (int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}

int sum(int x) 求x的前缀和
{
    int res = 0;
    for (int i = x; i; i -= lowbit(i)) res += tr[i];
    return res;
}

树状数组题解
1.楼兰图腾

大致思路:对于点i,求出左边和右边比i小的个数相乘,即为在i点∧的个数,同理,求出左边和右边比i大的个数相乘,即为在i点V的个数。
故可以用两个数组记录
Low[i]表示左边比第i个位置小的数的个数
Great[i]表示左边比第i个位置大的数的个数
tr[i]求和表示用于记录小于等于i个数的总和

const int N=200010;

int n;
int a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值