求序列A中每个数的左边比它小的数的个数(树状数组)

给定一个有N个正整数的序列A(N<=10^5,A[i]<=10^5),对序列中的每一个数,求出序列中它左边比它小的数的个数。

思路:树状数组的经典应用(裸题)

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4
 5 using namespace std ;
 6
 7 const int N = 100010 ;
 8
 9 int c[N] ;
10
11 int lowbit(int x){//取得最右边的一个1
12     return x&(-x) ;
13 }
14
15 int getSum(int x){//区间1~x的和 log(N)
16     int sum = 0 ;
17     for(int i=x;i>0;i-=lowbit(i)){
18         sum += c[i] ;
19     }
20     return sum ;
21 }
22
23 void update(int x,int v){//单点更新 log(N)
24     for(int i=x;i<=N;i+=lowbit(i)){
25         c[i] += v ;
26     }
27 }
28
29
30 int main(){
31     int n, x ;
32     cin >> n ;
33
34     memset(c,0,sizeof c) ;
35
36     for(int i=0;i<n;i++){
37         cin >> x ;
38         update(x,1) ;
39         cout << getSum(x-1) << endl ;
40     }
41
42     return 0 ;
43 } 

原文地址:https://www.cnblogs.com/gulangyuzzz/p/12048533.html

时间: 2024-11-05 16:04:47

求序列A中每个数的左边比它小的数的个数(树状数组)的相关文章

树状数组求逆序数 。,。 蓝桥杯 小朋友排队

先介绍一下树状数组.什么是树状数组呢?树状数组(Binary Indexed Tree(BIT), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值:经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值(如果加入多个辅助数组则可以实现区间修改与区间查询).(度娘万岁) 假设A[]数组为存储原来的值得数组,C[]为树状数组. 我们定义:C[i] = A[i - 2^k

hdu5792 World is Exploding(多校第五场)树状数组求逆序对 离散化

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5792 题目描述:给你n个值,每个值用A[i]表示,然后问你能否找到多少组(a,b,c,d)四个编号,四个编号互不相同,然后a < b, c < d,a代表的值小于b代表的值,c代表的值大于d代表的值. 解题思路:先考虑a和b这两个编号,遍历每一个编号作为b,然后找到b前面有多少个小于b的值,就是对于这一个编号b合理的编号a,对于每一组a和b,就可以考虑c和d,能够满足条件c和d的很显然就是除去a和

NYOJ117&amp;&amp; 树状数组求逆序数

(转)树状数组可以用来求逆序数, 当然一般用归并求.如果数据不是很大, 可以一个个插入到树状数组中, 每插入一个数, 统计比他小的数的个数,对应的逆序为 i- getsum( data[i] ),其中 i 为当前已经插入的数的个数, getsum( data[i] )为比 data[i] 小的数的个数i- sum( data[i] ) 即比 data[i] 大的个数, 即逆序的个数但如果数据比较大,就必须采用离散化方法.一关键字的离散化方法:所谓离散化也就是建立一个一对一的映射. 因为求逆序时只

树状数组的改段求段详解

以下是对于如何利用树状数组进行区间修改和区间查询的简介 可以代替不需要lazy tag的线段树,且代码量和常数较小 首先你需要学会树状数组,如果不会的话以下先讲解黑匣子使用树状数组的姿势 首先定义一个数组 int c[N]; 并清空 memset(c, 0, sizeof c); 1.单点修改 : c[x] += y; 对应的函数是 change(x, y); 2.求前缀和 :  对应的函数是 int sum(x) 两种操作的复杂度都是O(logn) 模版如下 int c[N], maxn; i

求序列中满足Ai &lt; Aj &gt; Ak and i &lt; j &lt; k的组数 树状数组 HIT 2275 Number sequence

http://acm.hit.edu.cn/hoj/problem/view?id=2275 Number sequence   Source : SCU Programming Contest 2006 Final   Time limit : 1 sec   Memory limit : 64 M Submitted : 1632, Accepted : 440 Given a number sequence which has N element(s), please calculate

hdu 2838 Cow Sorting 树状数组求所有比x小的数的个数

Cow Sorting Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4766    Accepted Submission(s): 1727 Problem Description Sherlock's N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening.

hdu4417 树状数组(求指定区间比指定数小的数的个数)

http://acm.hdu.edu.cn/showproblem.php?pid=4417 Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover.

树状数组求逆序对:POJ 2299、3067

前几天开始看树状数组了,然后开始找题来刷. 首先是 POJ 2299 Ultra-QuickSort: http://poj.org/problem?id=2299 这题是指给你一个无序序列,只能交换相邻的两数使它有序,要你求出交换的次数.实质上就是求逆序对,网上有很多人说它的原理是冒泡排序,可以用归并排序来求出,但我一时间想不出它是如何和归并排序搭上边的(当初排序没学好啊~),只好用刚学过的树状数组来解决了.在POJ 1990中学到了如何在实际中应用上树状数组,没错,就是用个特殊的数组来记录即

HDU 1394 树状数组+离散化求逆序数

对于求逆序数问题,学会去利用树状数组进行转换求解方式,是很必要的. 一般来说我们求解逆序数,是在给定一串序列里,用循环的方式找到每一个数之前有多少个比它大的数,算法的时间复杂度为o(n2). 那么我们通过树状数组可以明显提高时间效率. 我们可以按照排列的顺序依次将数字放入树状数组中,并依次更新预与之相关联的树状数组元素.那么在将其更新完毕后,我们知道每个数对应的树状数组元素的左边的数肯定比它小,我们在以序列顺序依次更新树状数组时,如果有值在它前面出现,那么它对应的树状数组元素(在这个题目里存放的