首页 > 其他分享 >树状数组

树状数组

时间:2023-01-19 22:45:10浏览次数:51  
标签:树状 int res 个数 tr 数组

acwing - 楼兰图腾

树状数组操作

 

(1)add(x, k)函数表示将序列中第x个数加上k, 同时范围覆盖到x的数也要加上k

实现:

void add(int x, int k)
{
    for(int i = x; i <= n; i += lowbit(i))
        tr[i] += k;
}

(2)sum(x)函数为查询操作,查询前x个数的和,每次将下标-lowbit(i)之后,所有t[i]的和

实现:

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

楼兰图腾

#include <iostream>
#include <cstring>
using namespace std;

const int N = 200010;

typedef long long LL;

int n;
int Greater[N], Lower[N];      
//Greater[i]表示在第i个位置左边,比a[i]大的数的个数
//Lower[i]表示在第i个位置左边,比a[i]小的数的个数

int tr[N];     //tr[i]表示树状数组i覆盖范围内的数的个数和
int a[N];


//返回x的最后一位1
int lowbit(int x)
{
    return x & (-x);
}

/*将x以及所有受x影响的tr[i](即覆盖范围包含x的tr[i])都+c

举个例子感受一下原因:
若add(3,1),即向序列中加入一个数字3,此时tr[3] += 1, tr[4] += 1
sum(5)表示此时树状数组中<=5的数字的个数和,而sum(5) = tr[1] + tr[4]
因此向序列中加入一个3,通过影响tr[4]的值,从而使sum(5) += 1,统计到刚刚加入序列中的3
*/
void add(int x, int c)
{
    for(int i = x; i <= n; i += lowbit(i))
        tr[i] += c;
}

//求所有已经加入树状数组中的<=x的数字的个数和
int sum(int x)
{
    int res = 0;
    for(int i = x; i; i -= lowbit(i))
        res += tr[i];
    return res;
}

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++)
        scanf("%d", &a[i]);

    //从左往右开始统计,求出在第i个位置左边,小于或大于a[i]的数的个数
    for(int i = 1; i <= n; i ++)
    {
        int j = a[i];
        Greater[i] = sum(n) - sum(j);  //采用前缀和的思想,用小于等于n的数的个数—小于等于a[i]的数的个数
        Lower[i] = sum(j - 1);
        add(j, 1);
    }

    memset(tr, 0, sizeof tr);    //重置tr数组

    //从右往左开始统计,求出在第i个位置右边,小于或大于a[i]的数的个数
    LL res1 = 0, res2 = 0;
    for(int i = n; i; i --)
    {
        int j = a[i];
        res1 += (LL)Greater[i] * (sum(n) - sum(j));    //乘法原理
        res2 += (LL)Lower[i] * sum(j - 1);
        add(j, 1);
    }
    printf("%lld %lld", res1, res2);
    return 0;
}

 

标签:树状,int,res,个数,tr,数组
From: https://www.cnblogs.com/breeze-ku/p/17062251.html

相关文章

  • Vue 中如何监测数组的变化?
    在Vue中,如果直接对数组进行操作,比如使用下标直接修改元素,Vue是无法监测到这种变化的,导致无法触发视图更新。针对该问题,总结如下解决方法:一、使用Vue.js提供的方法来......
  • 数组
    数组数组的定义数组是相同类型数据的有序组合数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成其中,每一个数据称作一个数组元素,每一个数组元素可以通......
  • 树状数组笔记整理
    树状数组介绍树状数组,顾名思义,就是树状的一维数组。二叉树同样也可以用一维数组存储。我们以二叉树进行类比。如图所示,图中节点的序号就是存在数组中的下标。记父节点......
  • 前后端不分离的项目中使用jq动态遍历数组渲染页面,显示从第2条数据开始渲染
    前后端不分离的项目中使用jq动态遍历数组渲染页面,显示从第2条数据开始渲染 后台跳转页面携带参数processVos为数组,具体内容为:varprocessVos=[{id:1......
  • 将101到200之间的值中的质数 放入数组中
    packagecom.fqs.demo;publicclassZhiNumber{publicstaticvoidmain(String[]args){intstart=101;//被除数开始的值,包含本身......
  • Array 数组
    概念Array数组是有序的元素序列。语法newArray(length)newArray(element1)newArray(element1,element2)newArray(element1,element2,element3)newArray(e......
  • ZROJ369 Tiny Counting - 容斥 - 树状数组 -
    题目链接:http://zhengruioi.com/contest/101/problem/369题解:枚举\(i\),表示钦定了\(b\)或者\(d\)位于\(i\)处不妨设是\(b\)位于\(i\)处,\(d\)同理\(a\)......
  • javaScript数组的sort()方法
    javaScript数组的sort()方法:今天再学习javaScript的数组的Array.sort()方法时,遇到了一个很有意思的问题,这个方法,直接调用,其实并不会得到我们想要的排序,而是会以一种很机械......
  • java-数组相关的算法(尚硅谷)
    1.数组元素的赋值(杨辉三角、回形数等)2.求数值型数组中元素的最大值、最小值、平均数、总和等3.数组的复制、反转、查找(线性查找、二分法查找)4.数组元素的排序算法一......
  • 「学习笔记」后缀数组
    后缀数组,即\(sa\)数组,代表的是一个字符串所有后缀按照字典序排序后,排名第\(i\)的后缀的开头位置。举个例子:aabaaab的所有后缀有:编号前缀1aabaaab2......