POJ 2299 Ultra-QuickSort (树状数组+离散化 求逆序数)
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Input
Output
Sample Input
5
9 1 0 5 4
3
1 2 3
0
Sample Output
6
0 给你一个排序,让你求出这个排序中的逆序数.算是自己写的树状数组的第一道题吧,这个题首先用到离散化思想.
因为每个数都是小于1e9,而n的范围不超过5e5,而且我们只关心这些数的大小关系,所以我们就把这些数全部映射到1~n,然后再按照排好序的位置插进去就行了
这样子是不会影响最后算逆序数的.映射后的序列为reflect
接下来求逆序数,这时要用到树状数组,树状数组的功能是用来求数组前缀和的,我们假想有一个长度为n的数组,它现在每一位初始化为0
我们按照位置顺序将reflect中的每一个数插入到树状数组中,假设我们现在插入的数是第i个数,它的值为x
那么我就把刚刚假想的数组的第x位置变为1,即代表x被插入到该序列
那么每一次对于ans怎样+呢?
我们可以定义sum(x) x及小于x的数中有多少个元素已经被插入
这样的话sum(x)就是我们刚刚那个假想数组的前缀和了,我们用树状数组可以求
对于插入的第i个数,我们的ans+=i-sum(x),因为x是第i个数插进来的,之前插进来小于等于x的数为sum(x)
两者做差就是在x之前插入,而且值要大于x的数字的个数
代码如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn =;
int reflect[maxn];
int c[maxn];
int n;
int lowbit (int x)
{
return x&(-x);
}
struct Node
{
int val,pos;
};
Node node[maxn];
bool cmp (Node q1,Node q2)
{
return q1.val<q2.val;
} void update (int x)
{
while (x<=n){
c[x]+=;//将我们想象的数组x位置附为1,直接就加到c[x]上了
x+=lowbit(x);//找父节点
}
}
int getsum (int x)
{
int sum=;
while (x>){
sum+=c[x];
/*求和时可以看作将x用二进制表示
temp=x;
每次加上c[temp],再把temp最后1位置上的值改成0
最后变成0时就求完了
如:求 101001
temp=101001 -> sum+=c[101001]
-> temp=101000 -> sum+=c[101000]
-> temp=100000 -> sum+=c[100000]
-> temp=000000 求完了
*/
x-=lowbit(x);
}
return sum;
}
int main()
{
//freopen("de.txt","r",stdin);
while (scanf("%d",&n)&&n){
for (int i=;i<=n;++i){
scanf("%d",&node[i].val);
node[i].pos=i;
}
sort(node+,node + n + , cmp);
for (int i=;i<=n;++i) reflect[node[i].pos]=i;//离散化映射到1~n
for (int i=;i<=n;++i) c[i]=;//初始化树状数组
long long ans=;
for (int i=;i<=n;++i){
update(reflect[i]);//插入一个数,更新一下
ans+=i-getsum(reflect[i]);//ans加一下
}
printf("%lld\n",ans);
}
return ;
}
POJ 2299 Ultra-QuickSort (树状数组+离散化 求逆序数)的更多相关文章
- HDU 1394 树状数组+离散化求逆序数
对于求逆序数问题,学会去利用树状数组进行转换求解方式,是很必要的. 一般来说我们求解逆序数,是在给定一串序列里,用循环的方式找到每一个数之前有多少个比它大的数,算法的时间复杂度为o(n2). 那么我们 ...
- CF 61E 树状数组+离散化 求逆序数加强版 三个数逆序
http://codeforces.com/problemset/problem/61/E 题意是求 i<j<k && a[i]>a[j]>a[k] 的对数 会 ...
- POJ 2299 Ultra-QuickSort(树状数组+离散化)
http://poj.org/problem?id=2299 题意:给出一组数,求逆序对. 思路: 这道题可以用树状数组解决,但是在此之前,需要对数据进行一下预处理. 这道题目的数据可以大到999,9 ...
- POJ - 2299 Ultra-QuickSort 【树状数组+离散化】
题目链接 http://poj.org/problem?id=2299 题意 给出一个序列 求出 这个序列要排成有序序列 至少要经过多少次交换 思路 求逆序对的过程 但是因为数据范围比较大 到 999 ...
- POJ 2299 树状数组+离散化求逆序对
给出一个序列 相邻的两个数可以进行交换 问最少交换多少次可以让他变成递增序列 每个数都是独一无二的 其实就是问冒泡往后 最多多少次 但是按普通冒泡记录次数一定会超时 冒泡记录次数的本质是每个数的逆序数 ...
- POJ 3067 - Japan - [归并排序/树状数组(BIT)求逆序对]
Time Limit: 1000MS Memory Limit: 65536K Description Japan plans to welcome the ACM ICPC World Finals ...
- poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)
题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular so ...
- poj 2299 Ultra-QuickSort(树状数组求逆序数)
链接:http://poj.org/problem?id=2299 题意:给出n个数,求将这n个数从小到大排序,求使用快排的需要交换的次数. 分析:由快排的性质很容易发现,只需要求每个数的逆序数累加起 ...
- poj 2299 Ultra-QuickSort(树状数组)
Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 67681 Accepted: 25345 ...
随机推荐
- flask入门到入土
# Flask ## 0.Flask简介 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用 ...
- visual studio code的使用
1.添加代码片段 参考:https://blog.csdn.net/qq_36370731/article/details/83014439 2.在vscode上运行Git 先打开vscode内置的G ...
- 韩老师CCNA学习笔记
1.MSCONFIG服务里面可以选择隐藏Windows服务,就能看出程序安装的服务.即使显示已停止,仍可能在运行 2.命令行输入netstat -anbo ,显示当前连接和端口,数字显示,以及程序的路 ...
- [CSP-S模拟测试]:english(可持久化Trie+启发式合并)
题目传送门(内部题24) 输入格式 第一行有$3$个整数$n,opt$,$opt$的意义将在输出格式中提到.第二行有$n$个整数,第$i$个整数表示$a_i$. 输出格式 若$opt=1$,输出一行一 ...
- [CSP-S模拟测试]:山洞(DP+快速幂)
题目传送门(内部题17) 输入格式 一行两个整数$n$,$m$,含义如题面. 输出格式 一行一个整数,表示方案数模$1e9+7$. 样例 样例输入1: 4 6 样例输出1: 样例输入2: 707 18 ...
- Java程序执行的过程
ava程序执行的过程: Step1:将字节码加入内存: Step2:对字节码进行合法性检查: Step3:jvm会为每个字节码文件都生成一个对象(class): Step4:执行静态代码块,初始化静态 ...
- Hive if和coalesce函数
链接:https://blog.csdn.net/qq_26442553/article/details/79465417 if 函数举例:
- Java学习之多线程(线程安全问题及线程同步)
一.线程安全问题产生前提:1.多线程操作共享数据2.线程任务中有多条代码 class Ticket implements Runnable { //2.共享数据 private int num = 1 ...
- redis 入门之有序集合
zadd 将一个或多个 member 元素及其 score 值加入到有序集 key 当中.如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 ...
- OpenCV2马拉松第9圈——再谈对照度(对照度拉伸,直方图均衡化)
收入囊中 lookup table 对照度拉伸 直方图均衡化 葵花宝典 lookup table是什么东西呢? 举个样例,假设你想把图像颠倒一下,f[i] = 255-f[i],你会怎么做? for( ...