poj2299 Ultra-QuickSort 树状数组求逆序数
Ultra-QuickSort
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 49587 | Accepted: 18153 |
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.
Ultra-QuickSort produces the output
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<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=(1<<29); int n; ll a[maxn]; ll b[maxn],m; ll c[maxn]; int lowbit(int x) { return x&(-x); } ll sum(int p) { ll res=0; while(p>0){ res+=c[p]; p-=lowbit(p); } return res; } void add(int p,ll x) { while(p<=m){ c[p]+=x; p+=lowbit(p); } } int main() { while(cin>>n,n){ MS0(c); REP(i,1,n){ scanf("%I64d",&a[i]); b[i]=a[i]; } sort(b+1,b+n+1); m=unique(b+1,b+n+1)-(b+1); ll ans=0; REP(i,1,n){ int x=lower_bound(b+1,b+n+1,a[i])-b; add(x,1); ans+=sum(m)-sum(x); } printf("%I64d ",ans); } return 0; }