Ultra-QuickSort
Time Limit: 7000MS |
|
Memory Limit: 65536K |
Total Submissions: 22147 |
|
Accepted: 7897 |
Description
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
此题大意:找逆序数有多少个,逆序数就是那一个序列中,右边的数比左边的数大的个数之和。其实就是和找冒泡的次数一样,不过用冒泡来做,50万个数据直接死亡,这道题可以用树状数组来做,之前不会做,看到解题报告中有说树状数组可以,就开始尝试写,后来发现竟然可以这样想:每次找前面(左边)的数比自己大的个数的总和!!!这样子想的话树状数组可以轻松解决。
不过还有一个问题,就是他输入的数据的值很大0 ≤ a[i] ≤ 999,999,999,但是数据的数量不是很大n < 500,000 ,所以用到离散化解决!!!
链接:http://poj.org/problem?id=2299
代码:
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
using namespace std;
int b[500005], c[500005];
int n;
struct node
{
int num, id;
}a[500005];
bool cmp(node a, node b)
{
return a.num < b.num;
}
void update(int i, int x)
{
while(i <= n)
{
c[i] += x;
i += i&(-i);
}
}
int sum(int i)
{
int sum = 0;
while(i > 0)
{
sum += c[i];
i -= i&(-i);
}
return sum;
}
int main()
{
int i;
long long ans;
while(scanf("%d", &n), n)
{
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
for(i = 1; i <= n; i++)
{
scanf("%d", &a[i].num); //输入数值num
a[i].id = i; //记录序号id
}
///开始离散化
sort(a+1, a+n+1, cmp); //先排序
/*因为a[1].num是最小的,id是它的位置,所以b[a[1].id]=1最小,
最小的数变成1,第二小的变成2,如此类推从而达到离散化*/
b[a[1].id] = 1;
for(i = 2; i <= n; i++)
{
if(a[i].num != a[i-1].num)
b[a[i].id] = i;
else b[a[i].id] = b[a[i-1].id];
}
///离散化完毕
ans = 0;
for(i = 1; i <= n; i++)
{
update(b[i], 1);
//这里很巧妙,每一次更新后,判断此数比左边的数小的数有多少
ans += (sum(n)-sum(b[i]));
}
//从而求到:右边的数比左边的数大的个数的总和
printf("%I64d\n", ans);
}
return 0;
}
分享到:
相关推荐
【标题】"POJ2299-Ultra-QuickSort"是北京大学在线判题系统POJ上的一道编程题目,其主要涉及的算法是快速排序(Ultra-QuickSort)。快速排序是一种高效的排序算法,由C.A.R. Hoare在1960年提出。它的基本思想是采用...
北京大学在线判题系统POJ(Problem Online Judge)是许多编程爱好者和学习者锻炼算法技能的平台,特别是对于初学者,它提供了很多基础题目来帮助理解并应用数据结构。本资源包含的是北大POJ初级题目的解题报告以及...
标题中的“图的深搜+树状数组练习 POJ 3321(JAVA)”指的是一个编程题目,其中涉及到图的深度优先搜索(DFS, Depth First Search)算法和树状数组(也称为线段树,Segment Tree)的数据结构。这个题目来源于POJ...
- 排序:快速排序、归并排序和堆排序,如POJ2299。 - 并查集:处理不相交集合问题,如POJ3349。 - 哈希表和二分查找:提高查找效率,如POJ2151。 - 哈夫曼树:用于数据压缩,如POJ3253。 - 堆:如POJ2299。 - ...
在`POJ1804-Brainman【借助Mergesort求逆序数O(nlogn)】.cpp`文件中,你应该能够找到使用归并排序算法计算逆序对的实现。这种方法相比于直接求解,虽然增加了额外的排序操作,但大大提高了时间效率,尤其在处理大...
根据给定的文件信息,我们可以总结出一份详细的IT知识训练计划,主要针对编程竞赛和算法学习,特别是聚焦于POJ(Problem Online Judge)平台上的题目训练。这份计划分为两个阶段,初级阶段和中级阶段,共计涉及了165...
- **解释**:树形数据结构的题目通常涉及树的遍历、查找等问题。 #### 2. 字符串 - **例题**:poj2388, poj2299 - **解释**:字符串问题通常涉及字符串的模式匹配、编辑距离等问题。 #### 3. 哈希表 - **例题**:...
【标题】"树状数组练习:POJ 3067" 树状数组,也称为线段树(Segment Tree),是一种高效的数据结构,用于处理区间查询和修改问题。在这个问题中,我们通过分析POJ 3067的题目来探讨如何应用树状数组解决实际问题。...
- **定义**:一种用于存储字符串集合的树形结构。 - **示例题目**: - poj2513 - **应用场景**:适用于字符串检索、自动补全等功能。 #### 四、搜索 **1. 深度优先搜索** - **定义**:一种递归的搜索方式,沿着图...
【标题】"树状数组练习:POJ 2481(JAVA)" 是一篇关于使用树状数组(也称为线段树)解决编程竞赛问题的文章。这篇文章可能详细讲解了如何运用这种数据结构来解决特定的问题POJ 2481。POJ(Programming Online Judge)...
### POJ 2352 Stars - 树状数组与线段树实现 #### 题目背景 POJ 2352 Stars 是一道经典的算法题目,它提供了使用树状数组或线段树来解决的可能性。这两种数据结构都是为了高效处理区间查询问题而设计的。在这篇...
标题“POJ3414-Pots”是一个编程竞赛题目,源自北京大学的在线判题系统POJ(Problem Online Judge)。这个题目主要考察的是算法设计和实现能力,通常涉及计算机科学中的数据结构和算法知识。 解题报告是参赛者在...
### ACM POJ PKU 最全题目分类解析 #### 动态规划(DP) 在计算机科学领域,动态规划(Dynamic Programming, DP)是一种重要的算法思想,主要用于解决多阶段决策过程中的优化问题。它通过将原问题分解成相互重叠的...
标题中的"POJ1002-487-3279【Hash+Qsort】"是指一个编程挑战题目,通常在在线编程平台上出现,比如北京大学的Peking Online Judge (POJ)。这个题目结合了哈希表(Hash)和快速排序(Qsort)两种算法来解决问题。哈希...
#### 1.8 数组逆序重放 (POJ 2687) - **题目描述**:给定一个整数数组,将其逆序排列。 - **关键知识点**: - 数组操作:定义数组并初始化。 - 循环结构:遍历数组进行逆序。 - 交换操作:交换数组元素的位置。 ...
POJ 2299 是一个经典的逆序数对算法题目,它要求计算一个序列中的逆序数对数量。该问题可以使用多种算法解决,包括暴力枚举、归并排序、树状数组等。 暴力枚举算法 暴力枚举算法是最简单的解决方法,它通过枚举...
【标题】"POJ2002-Squares"是一个经典的计算机编程题目,源自北京大学的在线判题系统(POJ,即PKU Online Judge)。这个题目主要涉及到算法设计和实现,尤其是数学和动态规划方面的知识。 【描述】"解题报告+AC代码...
标题中的“POJ1014-Dividing”是指北京大学在线编程平台POJ(Problemset Online Judge)上的一个问题编号为1014的题目。这个题目通常会涉及到计算机科学和算法设计,特别是优化问题的解决方案。这里的关键词是“DFS...
- POJ 3264、POJ 3368:树状数组的构造与更新。 #### 字符串匹配 - **题目示例**: - POJ 1961、POJ 2406:KMP算法的应用。 ### 其他问题 #### 贪心算法 - **题目示例**: - POJ 3411、POJ 1724:贪心策略的...