树状数组:可以动态维护前缀和,查询时间复杂度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