Ultra-QuickSort
Time Limit: 7000MS   Memory Limit: 65536K
Total Submissions: 52778   Accepted: 19348

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 题意:给一组数,每次只能交换相邻两个数的位置,问最少交换多少次,使得这个序列从小到大排序;
题解:求逆序数的对数 线段树:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define LL long long
#define MAX 500500
using namespace std;
int n,m;
struct node
{
int val,pos;
}num[MAX];
int sum[MAX<<2];
void pushup(int o)
{
sum[o]=sum[o<<1]+sum[o<<1|1];
}
void gettree(int o,int l,int r)
{
sum[o]=0;
if(l==r)
return ;
int mid=(l+r)>>1;
gettree(o<<1,l,mid);
gettree(o<<1|1,mid+1,r);
pushup(o);
} void update(int o,int l,int r,int pos)
{
if(l==r)
{
sum[o]+=1;
return ;
}
int mid=(l+r)>>1;
if(pos<=mid) update(o<<1,l,mid,pos);
else update(o<<1|1,mid+1,r,pos);
pushup(o);
}
int find(int o,int l,int r,int L,int R)
{
if(L<=l&&R>=r)
return sum[o];
int mid=(l+r)>>1;
int ans=0;
if(L<=mid) ans+=find(o<<1,l,mid,L,R);
if(R>mid) ans+=find(o<<1|1,mid+1,r,L,R);
return ans;
}
bool cmp(node a,node b)
{
if(a.val!=b.val) return a.val<b.val;
else return a.pos<b.pos;
}
int main()
{
int j,i,t,k;
while(scanf("%d",&n),n)
{
gettree(1,1,n);
for(i=1;i<=n;i++)
{
scanf("%d",&num[i].val);
num[i].pos=i;
}
sort(num+1,num+1+n,cmp);
LL ant=0;
for(i=1;i<=n;i++)
{
update(1,1,n,num[i].pos);
ant+=i-find(1,1,n,1,num[i].pos);
}
printf("%lld\n",ant);
}
return 0;
}

  树状数组:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define LL long long
#define MAX 500500
using namespace std;
int n,m;
int c[MAX<<1];
struct node
{
int val,pos;
}num[MAX];
bool cmp(node a,node b)
{
if(a.val!=b.val)
return a.val<b.val;
else
return a.pos<b.pos;
}
void update(int x)
{
while(x<=n)
{
c[x]+=1;
x+=x&-x;
}
}
LL sum(int x)
{
LL ans=0;
while(x>=1)
{
ans+=c[x];
x-=x&-x;
}
return ans;
}
int main()
{
int j,i,t,k;
while(scanf("%d",&n),n)
{
for(i=1;i<=n;i++)
{
scanf("%d",&num[i].val);
num[i].pos=i;
}
sort(num+1,num+n+1,cmp);
memset(c,0,sizeof(c));
LL ant=0;
for(i=1;i<=n;i++)
{
update(num[i].pos);
ant+=i-sum(num[i].pos);
}
printf("%lld\n",ant);
}
return 0;
}

  

poj 2299 Ultra-QuickSort(求逆序对)的更多相关文章

  1. poj 2299 Ultra-QuickSort (归并排序 求逆序数)

    题目:http://poj.org/problem?id=2299 这个题目实际就是求逆序数,注意 long long 上白书上的模板 #include <iostream> #inclu ...

  2. poj 2299 Ultra-QuickSort 归并排序求逆序数对

    题目链接: http://poj.org/problem?id=2299 题目描述: 给一个有n(n<=500000)个数的杂乱序列,问:如果用冒泡排序,把这n个数排成升序,需要交换几次? 解题 ...

  3. POJ 2188线段树求逆序对

    题目给的输入是大坑,算法倒是很简单-- 输入的是绳子的编号wire ID,而不是上(或下)挂钩对应下(或上)挂钩的编号. 所以要转换编号,转换成挂钩的顺序,然后再求逆序数. 知道了这个以后直接乱搞就可 ...

  4. Poj 2299 Ultra-QuickSort(归并排序求逆序数)

    一.题意 给定数组,求交换几次相邻元素能是数组有序. 二.题解 刚开始以为是水题,心想这不就是简单的冒泡排序么.但是毫无疑问地超时了,因为题目中n<500000,而冒泡排序总的平均时间复杂度为, ...

  5. POJ 2299 Ultra-QuickSort 离散化加树状数组求逆序对

    http://poj.org/problem?id=2299 题意:求逆序对 题解:用树状数组.每读入一个数x,另a[x]=1.那么a数列的前缀和s[x]即为x前面(或者说,再x之前读入)小于x的个数 ...

  6. 树状数组求逆序对:POJ 2299、3067

    前几天开始看树状数组了,然后开始找题来刷. 首先是 POJ 2299 Ultra-QuickSort: http://poj.org/problem?id=2299 这题是指给你一个无序序列,只能交换 ...

  7. POJ 2299树状数组求逆序对

    求逆序对最常用的方法就是树状数组了,确实,树状数组是非常优秀的一种算法.在做POJ2299时,接触到了这个算法,理解起来还是有一定难度的,那么下面我就总结一下思路: 首先:因为题目中a[i]可以到99 ...

  8. Ultra-QuickSort POJ - 2299 树状数组求逆序对

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

  9. POJ 2299 求逆序对个数 归并排序 Or数据结构

    题意: 求逆序对个数 没有重复数字 线段树实现: 离散化. 单点修改,区间求和 // by SiriusRen #include <cstdio> #include <cstring ...

随机推荐

  1. github概念和实战

    fork: 通过fork操作,你将拥有了别人创建的repo的ownership,但是url却变成了/youraccount/repo,这时你将可以做git push操作 clone: 该命令是直接将r ...

  2. Codeforces 424 B Megacity【贪心】

    题意:给出城市(0,0),给出n个坐标,起始人数s,每个坐标k个人, 每个坐标可以覆盖到半径为r的区域,r=sqrt(x*x+y*y)的区域,问最小的半径是多少,使得城市的总人数大于等于1000000 ...

  3. mongodb数据备份与还原

    1)简单数据的导出与导入导出:./mongoexport -d test -c users -o /tmp/users.out 导入:./mongoimport -d test -c users /t ...

  4. Servlet的延迟加载和预加载

    我们什么时候使用了延迟加载呢? 先从hibernate引入这个概念吧. hibernate使用lazy属性设置延迟加载,load方法会使用延迟加载. 举个例子: 一个学生有多部手机,如果使用了延迟加载 ...

  5. tableView的设置

    TableView的设置 1.设置table头部和底部的view // 底部(宽度固定是320) tableView.tableFooterView = footer; // 头部(宽度固定是320) ...

  6. php的webservice的soapheader认证问题

    参数通过类传输:class authentication_header {       private $username;       private $password;       public ...

  7. 【英语】Bingo口语笔记(51) - 相信怀疑的表达

  8. mysql利用存储过程批量插入数据

    最近需要测试一下mysql单表数据达到1000W条以上时增删改查的性能.由于没有现成的数据,因此自己构造,本文只是实例,以及简单的介绍. 首先当然是建表: [sql]view plaincopy CR ...

  9. c排序算法大全

    排序算法是一种基本并且常用的算法.由于实际工作中处理的数量巨大,所以排序算法 对算法本身的速度要求很高. 而一般我们所谓的算法的性能主要是指算法的复杂度,一般用O方法来表示.在后面将给出详细的说明.& ...

  10. 五种开源协议的比较(BSD,Apache,GPL,LGPL,MIT)(整理)

    BSD开源协议(original  BSD license.FreeBSD  license.Original  BSD license) BSD开源协议是一个给于使用者很大自由的协议.基本上使用者可 ...