您的位置:首页 > 其它

PKU 2299 【逆序数+树状数组】

2010-05-18 11:27 477 查看
Ultra-QuickSort
Time Limit: 7000MSMemory Limit: 65536K
Total Submissions: 14909Accepted: 5253
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

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: