题意:给出一个序列,求至少需要用到多少次操作,才能将序列从小到大排序。

思路:

  数据量很大,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 (排序+数据离散化+求顺序数)的更多相关文章

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

    In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a seque ...

  2. POJ 2299 【树状数组 离散化】

    题目链接:POJ 2299 Ultra-QuickSort Description In this problem, you have to analyze a particular sorting ...

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

    题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular so ...

  4. poj 2299 Ultra-QuickSort(树状数组求逆序数)

    链接:http://poj.org/problem?id=2299 题意:给出n个数,求将这n个数从小到大排序,求使用快排的需要交换的次数. 分析:由快排的性质很容易发现,只需要求每个数的逆序数累加起 ...

  5. POJ 2299 Ultra-QuickSort (树状数组 && 离散化&&逆序)

    题意 : 给出一个数n(n<500,000), 再给出n个数的序列 a1.a2.....an每一个ai的范围是 0~999,999,999  要求出当通过相邻两项交换的方法进行升序排序时需要交换 ...

  6. POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)

    题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...

  7. POJ 2299 Ultra-QuickSort 归并排序、二叉排序树,求逆序数

    题目链接: http://poj.org/problem?id=2299 题意就是求冒泡排序的交换次数,显然直接冒泡会超时,所以需要高效的方法求逆序数. 利用归并排序求解,内存和耗时都比较少, 但是有 ...

  8. POJ 2299 Ultra-QuickSort (树状数组 && 离散化)

    题意 : 给出一个数n(n<500,000), 再给出n个数的序列 a1.a2.....an每一个ai的范围是 0~999,999,999  要求出当通过相邻两项交换的方法进行升序排序时需要交换 ...

  9. POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)

    POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...

随机推荐

  1. 分布式PostGIS系列【2】——pgpool-II

    一.pgpool-II简介 二.pgpool-II安装与配置 三.分布式Postgis性能测试

  2. upTodown

         ------->>>  从左图变为有图,并实现将左图上面的信息隐藏. <img src="../images/up.gif" border=&qu ...

  3. 隐藏虚拟键盘,解决键盘挡住UITextField问题

    再正式开始之前,先来介绍一下IOS的键盘类型: 一.键盘风格 UIKit框架支持8种风格键盘 ? 1 2 3 4 5 6 7 8 9 10 typedef enum {      UIKeyboard ...

  4. C语言 电梯函数

    #include <stdio.h> #include <time.h> #include <stdlib.h> void test(){//汉字输出 printf ...

  5. 12.iscsi-target

    server: 环境:rhel7.2  软件包:targetcli-2.1.fb41-3.el7.noarch,selinux-policy-targeted-3.13.1-60.el7.noarch ...

  6. 《怎样实现通过shell脚本将用户踢出系统》

    下面是一个将用户踢出系统的脚本: #!/bin/bashread -p "input your username " userps aux | grep "^$user& ...

  7. ISE 中使用system generate

    本文讲解简单的ISE中使用system generate,system generate基本使用规则在此不详细说明可以见博客http://blog.csdn.net/xiabodan/article/ ...

  8. MySQL基础操作命令

    MySQL基础操作命令 1. 查看MySQL进程 ps -ef|grep mysql |grep -v grep 2. 查看MySQL端口 ss -lnt | grep 3306 3. MySQL的启 ...

  9. 转:const“变量”、define的常量和static 变量

    首先讲C编译器的内存分配: 代码区 数据区 用户区=线程栈+堆 其中的数据区存储:常量(define)+静态变量(static)+符号集(const)+全局变量   然后讲一下编译的大致顺序: 注释- ...

  10. python初试牛刀

    需求:在L7的一台机器上做nginx配置,然后代码分发到别的所有的机器上.由于目录中有很多配置文件,而且防止误操作,需要修改配置之前先备份原配置.然后需要在运行修改配置的脚本之前,先弹出界面,告知操作 ...