PKU 2299 【逆序数+树状数组】
2010-05-18 11:27
477 查看
Ultra-QuickSort
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
Waterloo local 2005.02.05
题解:题目实际上就是求逆序数,由于n最多只有500000,所以首先离散化。
然后用树状数组解决:就是扫描原序列,累加在其前面且大于它的个数。
1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <algorithm>
5
6 using namespace std;
7 const int N = 500010;
8 int n;
9 int a
;
int C
;
int ori
;
int index;
int lowbit(int x)
{
return x & (-x);
}
int getSum(int x)
{
int tot = 0;
while(x>0)
{
tot += C[x];
x -= lowbit(x);
}
return tot;
}
void update(int x,int delta)
{
while(x<N)
{
C[x]+=delta;
x += lowbit(x);
}
}
int b_search(int val)
{
int l = 2,r = index;
while(l<r)
{
int m = l+(r-l)/2;
if(val==a[m])return m;
if(val<a[m])r= m;
else l = m+1;
}
return -1;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n!=0)
{
memset(C,0,sizeof(C));
for(int i=2;i<=n+1;i++)
{
scanf("%d",a+i);
ori[i] = a[i];
}
sort(a+2,a+2+n);
index = 3;
for(int i=2;i<=n;i++)
{
if(a[i]!=a[i+1])
{
a[index++] = a[i+1];
}
}
long long ans = 0;
update(b_search(ori[2]),1);
for(int i=3;i<=n+1;i++)
{
int t = b_search(ori[i]);
ans+= getSum(index+1) - getSum(t);
update(t,1);
}
printf("%lld\n",ans);
}
return 0;
}
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 14909 | Accepted: 5253 |
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 0Sample Output
6 0Source
Waterloo local 2005.02.05
题解:题目实际上就是求逆序数,由于n最多只有500000,所以首先离散化。
然后用树状数组解决:就是扫描原序列,累加在其前面且大于它的个数。
1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <algorithm>
5
6 using namespace std;
7 const int N = 500010;
8 int n;
9 int a
;
int C
;
int ori
;
int index;
int lowbit(int x)
{
return x & (-x);
}
int getSum(int x)
{
int tot = 0;
while(x>0)
{
tot += C[x];
x -= lowbit(x);
}
return tot;
}
void update(int x,int delta)
{
while(x<N)
{
C[x]+=delta;
x += lowbit(x);
}
}
int b_search(int val)
{
int l = 2,r = index;
while(l<r)
{
int m = l+(r-l)/2;
if(val==a[m])return m;
if(val<a[m])r= m;
else l = m+1;
}
return -1;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n!=0)
{
memset(C,0,sizeof(C));
for(int i=2;i<=n+1;i++)
{
scanf("%d",a+i);
ori[i] = a[i];
}
sort(a+2,a+2+n);
index = 3;
for(int i=2;i<=n;i++)
{
if(a[i]!=a[i+1])
{
a[index++] = a[i+1];
}
}
long long ans = 0;
update(b_search(ori[2]),1);
for(int i=3;i<=n+1;i++)
{
int t = b_search(ori[i]);
ans+= getSum(index+1) - getSum(t);
update(t,1);
}
printf("%lld\n",ans);
}
return 0;
}
相关文章推荐
- [树状数组 逆序对] poj 2299 Ultra-QuickSort
- Poj 2299 - Ultra-QuickSort 离散化,树状数组,逆序对
- Ultra-QuickSort (poj 2299 归并排序 || 树状数组 求逆序对)
- POJ 2299 树状数组求逆序对
- POJ 2299 Ultra-QuickSort (树状数组求逆序数+离散化)
- poj 2299 求逆序对 树状数组 归并排序
- poj2299 B - Ultra-QuickSort(线段树与树状数组求逆序对数)
- poj 2299 Ultra-QuickSort 【线段树 or 线段树+lazy or 树状数组 or 归并排序】 求逆序对
- 树状数组 求逆序数 poj 2299
- PKU 2299 求解逆序数(使用归并或者树状数组) 树状数组及入门知识
- POJ2299 Ultra-QuickSort(树状数组求逆序数+离散化)
- POJ 2299 Ultra-QuickSort (树状数组求逆序数 || 线段树 +离散化)
- POJ2299 树状数组求逆序数
- POJ 2299 Ultra-QuickSort 【树状数组求逆序数】
- poj 2299 Ultra-QuickSort (离散化,树状数组,逆序对)
- poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)
- poj 2299 树状数组求逆序对数+离散化
- 2299 Ultra-QuickSort 树状数组求逆序数
- 树状数组 求逆序数 poj 2299 离散化
- poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)