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 (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...
随机推荐
- score
#include<iostream> using namespace std; class student{ public: int Input() { ;i<;i++) { cou ...
- 十个最常见的Java字符串问题
翻译自:Top 10 questions of Java Strings 1.怎样比较字符串?用”==”还是用equals()? 简单地说,”==”测试两个字符串的引用是否相同,equals()测试两 ...
- Lucene使用IKAnalyzer分词实例 及 IKAnalyzer扩展词库
文章转载自:http://www.cnblogs.com/dennisit/archive/2013/04/07/3005847.html 方案一: 基于配置的词典扩充 项目结构图如下: IK分词器还 ...
- angular这个大梗的学习笔记
angular定义一个模块(module)及控制器(controller)的局部声明方法: var app=angular.module("Myapp",[]); myapp.co ...
- 使用自定义的item、Adapter和AsyncTask、第三方开源框架PullToRefresh联合使用实现自定义的下拉列表(从网络加载图片显示在item中的ImageView)
AsyncTask使用方法详情:http://www.cnblogs.com/zzw1994/p/4959949.html 下拉开源框架PullToRefresh使用方法和下载详情:http://ww ...
- Lucene 3.0
http://www.cnblogs.com/forfuture1978/archive/2010/02/22/1671487.html http://www.cnblogs.com/jiekzou/ ...
- 第29章 项目10:DIY街机游戏
1.问题 "Self-Defense Against Fresh Fruit":军士长指挥自己的士兵使用自我防御战术对抗以石榴.芒果.青梅和香蕉等新鲜水果入侵者.防御战术包括使用枪 ...
- EditPlus64的安装配置
下载地址,直接到360下载即可,下载完毕之后,进入如下网址,完后在线生成注册码 http://www.jb51.net/tools/editplus/ 以上是文本编辑器EditPlus的安装以及注册, ...
- Oracle计算两个整数的和与这两个整数的差与商
PL/SQL(Procedural Language/SQL)是一种过程化语言. PL/SQL都是以(BLOCK)块为基本单位,整个PL/SQL块分为三部分 1.声明(Declare) 2.执行(以B ...
- Daject初探 - 从Table模型得到Record模型
前言: 如果你还不知道Daject是什么,如何使用,可以浏览 http://www.cnblogs.com/kason/p/3577359.html github地址:https://github.c ...