Ultra-QuickSort
Time Limit: 7000MS   Memory Limit: 65536K
Total Submissions: 46995   Accepted: 17168

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

Source

           题目大意:给定若干个序列,假设是a[],求满足a[i]>a[j],且0<=i<j<=N的i,j的对数。
           首先,暴力的方法应该很好想,只要枚举每一个a[i],在枚举a[j](0<j<=i-1),若a[j]>a[i],则ans++。
          
           但是,这题给的序列的长度达到50w,若用暴力,时间复杂度为O(n^2),时间上过不了。为此可以针对这个序列中的数字大小区间做一个树状数组,按顺序把序列元素加进去,统计比它小的数字的个数,累加起来即可,时间复杂度O(nlogn),轻松通过。
 
           再但是,每个数字大小达到近百亿,若针对每个数字建立一个树状数组,空间上开不下(题目上只给了64M内存),所以要用离散化来解决(离散化讲解:http://baike.baidu.com/view/3392254.htm)具体方法是:先用结构体暂时存储序列,记下大小和位置,然后快排一下(虽然快排在序列完全逆序时可能卡到O(n^2),但应该不会在这里卡),再开一个reflect[],记录下离散化后的序列,这样若有50w个数,即使都很大,也终究有个大小之分,可以离散成1~50w,数组开至百万完全无压力。。
         
           就这样,时间和空间的问题都解决了。。。
 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
int N,M;
struct node{
int val;//记录大小
int pos;//记录这个数字的位置,方便以后排序
};
node a[];//暂时存储序列
int reflect[];//离散化后的序列
int BIT[];//树状数组 int cmp(const node &u,const node &v){
if(u.val<v.val) return ;
return ;
} int lowbit(int x){
return x&(-x);
}
/*
update
把数字依次插入,而不是直接建树的原因:
我们目的是求之前比当前数字小的数字个数,这样可以做到
ans+=i-sum(reflect[i])来更新,直接建树。。。不行
*/ void update(int x){
for(int i=x;i<=N;i+=lowbit(i)){
BIT[i]++;
}
} int sum(int k){
int ANS=;
for(int i=k;i>;i-=lowbit(i)){
ANS+=BIT[i];
}
return ANS;
}
int main(){
while(scanf("%d",&N)!=EOF&&N){
for(int i=;i<=N;i++){
scanf("%d",&a[i].val);
a[i].pos=i;
}
sort(a+,a+N+,cmp); for(int i=;i<=N;i++)
reflect[a[i].pos]=i;//离散化
for (int i = ; i <= N; ++i) BIT[i] = ;
//清空树状数组,,,千万不要忘记
LL ans=;
for(int i=;i<=N;i++){
update(reflect[i]);
ans+=(i-sum(reflect[i]));
}
printf("%lld\n",ans);
} return ;

最新文章

  1. 浅玩JavaScript的数据类型判断
  2. 沙盒SandBox
  3. 你眼中的async/await是什么样的?
  4. Android Sudoku应用挂掉的问题
  5. 增量与位置PID
  6. arm-none-eabi-gcc,makefile,stm官方库构建stm32f4xx工程
  7. hdu 4607 树的直径
  8. asp.net中js和jquery调用ashx的不同方法分享
  9. 【POJ3299】Humidex(简单的数学推导)
  10. GCD实现简单的单例类-Singletion
  11. php判断页面是电脑登录还是手机登录
  12. improper Advertising identifier [IDFA] Usage. Your app contains the Advertising Identifier [IDFA] AP
  13. SpringMVC注解@Component、@Repository、@Service、@Controller区别
  14. dotNet core 应用部署至 centos(超详解附截图)
  15. SpringBoot之处理JSON数据举例
  16. WM消息对应的Message消息中的Lparam和WParam
  17. react-native-pushy 热更新
  18. python 从外部获取传入的参数
  19. linux实用操作
  20. 纯css3棋盘图案背景以及45度斜纹背景

热门文章

  1. Java接口成员变量和方法默认修饰符
  2. db2 相关命令
  3. 【BZOJ4260】Codechef REBXOR Trie树+贪心
  4. java根据方法名动态调用invoke方法!
  5. 容器OOM相关
  6. Python2 显示 unicode
  7. REST Representational state transfer REST Resource Naming Guide Never use CRUD function names in URIs
  8. 【pip】【conda】
  9. 二.数据库游标对象cursor与实例
  10. OVN实战---《The OVN Gateway Router》翻译