求排列的逆序数之树状数组

代码实现

#include<iostream>

#include<cstdio>

#include<cstdlib>

using namespace std;

int num[100001];

int n,a[100001];

long long count=0;

void add(int x){

for(int i=x;i<=n;i+=(i&-i))num[i]++;

}

void query(int p){

for(int i=p; i; i -= (i & -i))count+=num[i];

}

int main(){

cin>>n;

for(int i=1;i<=n;i++)

cin>>a[i];

for(int i=n;i>=1;i--){

query(a[i]);

add(a[i]);

}

cout<<count;

}

反着做,也可正着做(求此数到n的区间和)

时间: 2024-11-06 13:40:00

求排列的逆序数之树状数组的相关文章

HDU 4417 类似求逆序数的树状数组

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2250    Accepted Submission(s): 1092 Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability

nyist oj 117 求逆序数 (归并排序&amp;&amp;树状数组)

求逆序数 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 现在,给你一个N个元素的序列,请你判断出它的逆序数是多少. 比如 1 3 2 的逆序数就是1. 输入 第一行输入一个整数T表示测试数据的组数(1<=T<=5) 每组测试数据的每一行是一个整数N表示数列中共有N个元素(2〈=N〈=1000000) 随后的一行共有N个整

poj 2299 Ultra-QuickSort 求逆序数,树状数组解法,详细解析

Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 44554   Accepted: 16195 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swappin

nyoj 117 求逆序数 【树状数组】+【离散化】

这道题的解法真的很好!!! 思路:建立一个结构体包含val和id, val就是输入的数,id表示输入的顺序.然后按照val从小到大排序,如果val相等,那么就按照id排序. 如果没有逆序的话,肯定id是跟i(表示拍好后的顺序)一直一样的,如果有逆序数,那么有的i和id是不一样的.所以,利用树状数组的特性,我们可以简单的算出逆序数的个数. 如果还是不明白的话举个例子.(输入4个数) 输入:9 -1 18 5 输出 3. 输入之后对应的结构体就会变成这样 val:9 -1 18 5 id:  1  

求逆序数(树状数组+离散化)

https://www.nowcoder.com/acm/contest/77/A 步骤: 首先离散化数组,对原数组进行排序并重新编号进另一个数组中 然后按原顺序 1)一点点更新树状数组(由于树状数组的元素主要是一个数组的部分元素的和,在这里由于只关心个数,所以元素和直接统计为个数和) 2)一点点求区间和 3)把计算的区间和都相加即可 其中add()和sum()是树状数组的基本操作 原文地址:https://www.cnblogs.com/MekakuCityActor/p/8474491.ht

[树状数组]求排列的逆序数

求排列的逆序数 题目描述 在Internet上的搜索引擎经常需要对信息进行比较,比如可以通过某个人对一些事物的排名来估计他(或她)对各种不同信息的兴趣,从而实现个性化的服务. 对于不同的排名结果可以用逆序来评价它们之间的差异.考虑1,2,-,n的排列i1,i2,-,in,如果其中存在j,k,满足 j < k 且 ij > ik,那么就称(ij,ik)是这个排列的一个逆序. 一个排列含有逆序的个数称为这个排列的逆序数.例如排列 263451 含有8个逆序(2,1),(6,3),(6,4),(6,

求逆序对 (树状数组版)

基本思想和线段树求解逆序数是一样的,前一篇<求逆序对 线段树版>也介绍过,先对输入数组离散,数组里的元素都不相同可以直接hash,存在相同的数话可以采用二分. 离散化后对于每个f[i],找到f[i]+1~ n中的个数,也就是到i这个位置,一共有多少比f[i]大的数,统计之后在将f[i]的位置上的数量加1. 这样一来统计的就是类似a[i]~n的和,可以想象成 把树状数组反过来统计,即统计的时候加lowbit,更新的时候减lowbit. 还是 以POJ 2299为例. #include <i

《程序设计与算法(二)算法基础》《第五周 分治》求排列的逆序数 11

011:求排列的逆序数 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 在Internet上的搜索引擎经常需要对信息进行比较,比如可以通过某个人对一些事物的排名来估计他(或她)对各种不同信息的兴趣,从而实现个性化的服务. 对于不同的排名结果可以用逆序来评价它们之间的差异.考虑1,2,…,n的排列i1,i2,…,in,如果其中存在j,k,满足 j < k 且 ij > ik, 那么就称(ij,ik)是这个排列的一个逆序. 一个排列含有逆序的个数称为这个排

逆序对 (树状数组 | | 归并排序

数组前面的一个元素 大于等于 后面的一个元素就是一个逆序对: 树状数组可以快速求前缀和,利用这一特性,可以求逆序对个数,见下: 用数组c[ i ]记录数组a[ n ]中i这一元素出现的次数 ,当a[ n ]中元素较大时可以离散化处理. 将a[ n ]从a[n -1]到a[0] 依次存到树状数组中,每存一个,对存的元素i求一次c[i]的前缀和, 这就是当前已扫描过的比i小的元素的个数,由于a[n]是倒着扫描的,所以此时比i小的元素都对应一个逆序对,统计之. #include <cstdio> #