POJ 2299 Ultra-QuickSort (排序+数据离散化+求顺序数)
题意:给出一个序列,求至少需要用到多少次操作,才能将序列从小到大排序。
思路:
数据量很大,n<500000,所以用冒泡模拟是超时的。 接下来就想到了求顺序数,总共需要交换的次数为每个数后面有多少个小于它的数的累加和。 如9 1 0 5 4,9后面比它小的有4个,1后面比它小的有1个,5后面比它小的有1个,总共为6个,即为答案。 求顺序数自然而然就是想到用树状数组。
但是这里有一点,那就是整数是0~999999999,数据太大,开不了那么大的数组。 由于n最多只有500000,所以最多有50万个不同的数据,所以将数据离散化减少数据范围。
用结构体存储数据最初的值value,以及一开始所在的位置idx,还有就是离散后的值ranks。 之后按值排序,从小到大开始赋值,最小的赋值1,然后依次递增。如果前后两个值相同,那么后一个赋前一个的ranks值。 最后再按照一开始所在的位置排序,从后往前赋值给数组a,a[i]的顺序数是前i-1个数中比a[i]小的个数,然后求累加和。 (按原来顺序赋值也可以,这样是求位于a[i]后面比a[i]小的个数的累加和,求的时候for循环从n开始递减)。
注意最后输出要用long long!!!
797ms,时间比别人长很多。。。
(不知道为什么,该代码在UVA10810 同样的一道题,竟然是WA。。。)
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm> using namespace std;
const int maxn=;
int a[maxn+]; //存储离散后的数据序列,顺序是原来序列的顺序
int c[maxn+]; //树状数组求和
int n;
struct Node{
int idx,ranks; //一开始的位置,离散后的值
long long value; //最初的值
}node[maxn+];
//按value从小到大排序
bool cmp1(const Node & tmp1,const Node & tmp2){
return tmp1.value<tmp2.value;
}
//按idx从小到大排序
bool cmp2(const Node & tmp1,const Node & tmp2){
return tmp1.idx<tmp2.idx;
}
int lowbit(int x){
return x&(-x);
}
void update(int value,int i){
while(i<=n){
c[i]+=value;
i+=lowbit(i);
}
}
int sum(int i){
int sum=;
while(i){
sum+=c[i];
i-=lowbit(i);
}
return sum;
}
int main()
{
long long data;
while(scanf("%d",&n)!=EOF){
if(n==)
break;
memset(c,,sizeof(c));
for(int i=;i<n;i++){
scanf("%I64d",&data);
node[i].value=data;
node[i].idx=i;
}
sort(node,node+n,cmp1); //将数据离散化
int num=;
node[].ranks=;
for(int i=;i<n;i++){
if(node[i].value==node[i-].value){
node[i].ranks=node[i-].ranks;
}
else{
num++;
node[i].ranks=num;
}
}
sort(node,node+n,cmp2);
for(int i=;i<n;i++){
a[n-i]=node[i].ranks;
}
//求顺序数
long long ans=;
for(int i=;i<=n;i++){
ans+=sum(a[i]-);
update(,a[i]);
}
printf("%I64d\n",ans);
}
return ;
}
POJ 2299 Ultra-QuickSort (排序+数据离散化+求顺序数)的更多相关文章
- POJ 2299 Ultra-QuickSort (树状数组+离散化 求逆序数)
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a seque ...
- POJ 2299 【树状数组 离散化】
题目链接:POJ 2299 Ultra-QuickSort Description In this problem, you have to analyze a particular sorting ...
- 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 (树状数组 && 离散化&&逆序)
题意 : 给出一个数n(n<500,000), 再给出n个数的序列 a1.a2.....an每一个ai的范围是 0~999,999,999 要求出当通过相邻两项交换的方法进行升序排序时需要交换 ...
- POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)
题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...
- POJ 2299 Ultra-QuickSort 归并排序、二叉排序树,求逆序数
题目链接: http://poj.org/problem?id=2299 题意就是求冒泡排序的交换次数,显然直接冒泡会超时,所以需要高效的方法求逆序数. 利用归并排序求解,内存和耗时都比较少, 但是有 ...
- POJ 2299 Ultra-QuickSort (树状数组 && 离散化)
题意 : 给出一个数n(n<500,000), 再给出n个数的序列 a1.a2.....an每一个ai的范围是 0~999,999,999 要求出当通过相邻两项交换的方法进行升序排序时需要交换 ...
- POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)
POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...
随机推荐
- 杭电ACM2058--The sum problem
http://acm.hdu.edu.cn/showproblem.php?pid=2058 以为简单的穷举就完了,结果是一直Time Limit Exceeded.. 这是代码: #include ...
- setbuf
setbuf是linux中的C函数,主要用于打开和关闭缓冲机制. setbuf函数具有打开和关闭缓冲机制.为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ(定义在stdio.h头文件中) ...
- SSH连接 NAT型 VirtualBox + LINUX
1.首先登录到虚拟机中的Linux系统,查看一下使用NAT网卡的IP地址. 2.关闭虚拟机. 3.依次点击 "设置 -> 网络 -> (网络地址转换)端口转发",其中需 ...
- C# 获取汉字的拼音首字母
/// <summary> /// 在指定的字符串列表CnStr中检索符合拼音索引字符串 /// </summary> /// <param name="CnS ...
- Messagebox.Show()常用参数设置
private void button1_Click(object sender, EventArgs e) { MessageBox.Show(" 1 个参数 " ); } pr ...
- Linux 下常用的压缩,解压方法
压缩命令: tar.gz 格式: tar -zcvf 自定义压缩文件名.tar.gz 被压缩文件名 zip 格式: zip -r 自定义压缩文件名.zip 被压缩文件名 如果要压缩整个文件夹,也 ...
- git管理和自动部署项目
当一个项目需要纳入到版本控制的时候,选择的工具还是比较多的,最常见的就是工具有CVS,SVN,GIT等.在平时的开发中视情况而定,从来就没有最好的版本控制工具,只有最适合的工具.在这里我习惯用git来 ...
- PHP:parse_str()字符串函数
parse_str()-把字符串解析成多个变量. 描述:void parse_str(sring $str [, array $arr]) 如果str是URL传递入的查询字符串(query stri ...
- Laravel 5 基础(二)- 路由、控制器和视图简介
查看 app/Http/routes.php Route::get('/', 'WelcomeController@index'); @是一个界定符,前面是控制器,后面是动作,表示当用户请求url / ...
- 修改UI中的值,无反应解决办法
var targetObj = $("<input name='mydate' class='easyui-datebox'>").appendTo("#id ...