【poj2299】树状数组求逆序对 Ultra-QuickSort

来源:互联网 发布:济宁网络问政平台app 编辑:程序博客网 时间:2024/06/06 07:28

Ultra-QuickSort

Time Limit: 7000MS Memory Limit: 65536K
Total Submissions: 56754 Accepted: 20985

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

这个什么就是求逆序对,题目那么多我也不知道在说什么,我英语渣
然后感觉用树状数组来求实际上好麻烦poi
还要先离散,然后两个sort,用归并应该会快一点吧
本来我不知道怎么做觉得挺神秘的,但说起来很简单,就是按大小把每个数加到自己的位置上,然后去统计,0~他自己之间有多少个数
然后,有些时候数比较大,我们就要离散什么的
大概就是这样,如果会了树状数组的单点修改 区间求和理解起来应该很轻松
然后是我的代码:

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<set>#include<map>#include<queue>#include<algorithm>#include<vector>#include<cstdlib>#include<cmath>#include<ctime>#include<stack>#define INF 2100000000#define ll long long#define clr(x)  memset(x,0,sizeof(x))#define clrmax(x)  memset(x,127,sizeof(x))using namespace std;inline int read(){    char c;    int ret=0;    while(!(c>='0'&&c<='9'))        c=getchar();    while(c>='0'&&c<='9')    {        ret=(c-'0')+(ret<<1)+(ret<<3);        c=getchar();    }    return ret;}#define M 500005#define lowbit(x) (x&(-x))int tree[M],n;struct node{    int num,f,no;}a[M];#define no(x) a[x].no#define num(x) a[x].num#define f(x) a[x].fbool com(node a,node b){    return a.num<b.num;}bool com2(node a,node b){    return a.no<b.no;}void add(int x){    for(int i=x;i<=n;i+=lowbit(i))        tree[i]++;}int get_min(int x){    int ret=0;    for(int i=x;i;i-=lowbit(i))        ret+=tree[i];    return ret;}int main(){    freopen("in.txt","r",stdin);    while(~scanf("%d",&n))    {        if(n==0)return 0;        clr(tree);        clr(a);        for(int i=1;i<=n;i++)        {            num(i)=read();            no(i)=i;        }        sort(a+1,a+n+1,com);        int cnt;        f(1)=cnt=1;        for(int i=2;i<=n;i++)        {            if(num(i)!=num(i-1))cnt++;            f(i)=cnt;        }        sort(a+1,a+n+1,com2);        ll ans=0;        for(int i=1;i<=n;i++)        {            add(f(i));            ans+=i-get_min(f(i));        }        cout<<ans<<'\n';    }}

大概就是这个样子,如果有什么问题,或错误,请在评论区提出,谢谢。

0 0
原创粉丝点击