POJ 2299 Ultra-QuickSort(树状数组+离散化+求逆序数)

简介: POJ 2299 Ultra-QuickSort(树状数组+离散化+求逆序数)

In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence
9 1 0 5 4 ,
Ultra-QuickSort produces the output
0 1 4 5 9 .
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Input
The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.
Output
For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.
Sample Input
5
9
1
0
5
4
3
1
2
3
0
Sample Output
6
0
题意就是输入一个n,接着输入n个数,然后求出这n个数的逆序数。

最简单的求逆序数就是用冒泡排序,每次比较,如果交换说明整两个数是逆序的,ans++,也就是说冒泡排序交换次数就是逆序数;但是时间复杂度是O(n^2).
再就是可以用归并排序来求逆序数,隐隐约约记得之前做过一道题是可以的来求的,虽然现在忘了啊。
这里用树状数组来求。

先说离散化
如果数据量少,但是数据范围大,那么开数组的话会浪费很大一部分空间,所以需要离散化处理(通俗点就是把离散较大的数据紧凑起来)

for (int i=1; i<=n; i++){
   
    scanf("%d", &init[i].val);
    init[i].order=i;
}
sort(init+1, init+n+1, cmp);
for (int i=1; i<=n; i++)
    a[init[i].order]=i;

这样最后a数组的下标就是原来数据的元素的order位置,值就是被处理后的值。从而做到把离散的数据紧凑起来,节省空间。
这样就是把9 1 0 5 4变成5 2 1 4 3
再说求逆序数
这里用树状数组来求,就是每个元素的前面比它大的数量的和就是最终的逆序数。

在说明一点,i-sum(a[i])是本来一共有i个数,sum(a[i])是所有小于等于a[i]的个数,相减就是大于a[i]的个数,也就是在新的数前面大于它的元素的个数。

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

int n;
int a[500005];
int c[500005];
struct node{
   
    int order;
    int val;
}init[500005];
int cmp(node a, node b){
   
    return a.val<b.val;
}
int lowbit(int x){
   
    return x&(-x);
}
void update(int index, int val){
   
    while (index<=n){
   
        c[index]+=val;
        index+=lowbit(index);
    }
}
int sum(int index){
   
    int ans=0;
    while (index>=1){
   
        ans+=c[index];
        index-=lowbit(index);
    }
    return ans;
}
int main(){
   
    while (scanf("%d", &n) && n){
   
        for (int i=1; i<=n; i++){
   
            scanf("%d", &init[i].val);
            init[i].order=i;
        }
        sort(init+1, init+n+1, cmp);
        for (int i=1; i<=n; i++)
            a[init[i].order]=i;
        memset(c, 0, sizeof(c));
        long long ans=0;
        for (int i=1; i<=n; i++){
   
            update(a[i], 1);
            ans+=(i-sum(a[i]));
        }
        printf("%lld\n", ans);
    }
    return 0;
}
相关文章
|
人工智能 Rust 前端开发
前端界的未来趋势:掌握这些新技术,让你的作品走在时代前沿!
【10月更文挑战第30天】前端开发正以前所未有的速度发展,新技术层出不穷。本文探讨了AI助手(如GitHub Copilot)、低代码/无代码平台、跨平台技术(如React Native)和WebAssembly等未来主流技术,并附上示例代码,帮助你走在时代前沿。
669 1
|
JavaScript 前端开发 API
详解队列在前端的应用,深剖JS中的事件循环Eventloop,再了解微任务和宏任务
该文章详细讲解了队列数据结构在前端开发中的应用,并深入探讨了JavaScript的事件循环机制,区分了宏任务和微任务的执行顺序及其对前端性能的影响。
|
人工智能 自然语言处理 安全
AI战略丨大模型时代,基金投顾AI应用探索
AI战略丨大模型时代,基金投顾AI应用探索
|
小程序 API 开发者
【异常解决】“errcode“:47003,“errmsg“:“argument invalid! data.date4.value invalid rid:xxxxxx
【异常解决】“errcode“:47003,“errmsg“:“argument invalid! data.date4.value invalid rid:xxxxxx
2172 0
【异常解决】“errcode“:47003,“errmsg“:“argument invalid! data.date4.value invalid rid:xxxxxx
|
分布式计算 Java Serverless
EMR Serverless Spark 实践教程 | 通过 spark-submit 命令行工具提交 Spark 任务
本文以 ECS 连接 EMR Serverless Spark 为例,介绍如何通过 EMR Serverless spark-submit 命令行工具进行 Spark 任务开发。
1052 7
EMR Serverless Spark 实践教程 | 通过 spark-submit 命令行工具提交 Spark 任务
|
缓存 Java 开发者
一文详解Spring Bean循环依赖
本文主要梳理了Spring解决bean循环依赖的思路。
44057 31
|
前端开发 JavaScript
基于Html对父页面打开子页面Dialog()的使用
作者在使用基于QUI的前端项目中遇到一个问题:无法在Dialog组件中提交后刷新列表页面。经过搜索和努力,找到了解决方案。通过创建新的`top.Dialog()`,设置相关属性如标题、URL、尺寸,并在OK事件中调用子页面的提交方法及刷新列表的方法实现了需求。提供的代码示例展示了如何打开编辑窗体并处理提交事件以刷新列表。
349 0
|
Python
如何动态切换代理IP
如何动态切换代理IP
298 0
|
Java API Nacos
spring.config.import 是一个 Spring Cloud Config Server 的属性,
spring.config.import 是一个 Spring Cloud Config Server 的属性,【1月更文挑战第25天】【1月更文挑战第123篇】
3106 1
|
算法
关于Dijkstra算法
关于Dijkstra算法
324 0

热门文章

最新文章