[树状数组][逆序数]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

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0

思路:求逆序数;用树状数组?开不了c[999,999,999]这么大的数组;离散化即可;
AC代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lowbit(x) x&(-x)
typedef long long ll;
using namespace std;

int n;
int b[500010];
int c[500010];

struct A{
  int val,ind;
}a[500010];

bool cmp(A a,A b){
  return a.val<b.val;
}

void add(int x,int val){
  for(int i=x;i<=n;i+=lowbit(i)){
    c[i]+=val;
  }
}

int getsum(int x){
  int ret=0;
  for(int i=x;i>0;i-=lowbit(i)){
    ret+=c[i];
  }
  return ret;
}

int main()
{
    while(scanf("%d",&n)!=EOF&&n){for(int i=1;i<=n;i++) {scanf("%d",&a[i].val); a[i].ind=i;}
        sort(a+1,a+1+n,cmp);
        for(int i=1;i<=n;i++) b[a[i].ind]=i;//离散化
        ll ans=0; memset(c,0,sizeof(c));
        for(int i=1;i<=n;i++){
            add(b[i],1);
            ans+=(i-getsum(b[i]));
        }
        cout<<ans<<endl;
    }
    return 0;
}
posted @ 2018-05-25 16:01  l..q  阅读(162)  评论(0编辑  收藏  举报