码迷,mamicode.com
首页 > 其他好文 > 详细

POJ - 2299 - Ultra-QuickSort

时间:2017-08-20 00:42:04      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:题目   style   一个   opened   ace   ref   pen   UI   div   

题目链接 : POJ-2288

题目大意:

给你一组数,问你对这组数进行冒泡排序,需要进行多少次交换。

题目分析:

由于数据量很大,直接进行模拟冒泡排序的过程O(n) 必然是不可以的。

其实对于每个数 num [ i ],要考虑这个数进行了多少次变化,只需考虑num[i]前面有多少

个数大于num[i],即计算所有的逆序对数进行相加。

为了计算逆序对数,我们可以考虑使用树状数组。

首先因为num[i]最大为1e9,无法开出这么大的数组,但是我们观察最多只有五万个数,

所以我们可以考虑进行离散化,所以首先我进行了一个自己吓懵的离散化。

即把每个数替换成50000-该数为数组中第几大的数。

(为什么不直接使用第几大数替换?

因为数组数组只能查询区间1~i 有多少个数,而我们需要考虑的是i前面有多少个数大于i,

所以直接替换不方便查询)

然后进行套用树状树状即可。

(注意如果进行查询num[i],要查询num[i]-1,因为只有严格大于的数才可以,等于的不符合条件)

给出代码:

技术分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 int N=500000+10;
 8 const int inf=1e9+10;
 9 struct node
10 {
11     int id;
12     int grade;
13 }nodes[500000+10];
14 int vis[500000+10];
15 int num[500000+10];
16 int bit(int x)
17 {
18     return (x&(-x));
19 }
20 bool cmp(const node& a,const node& b)
21 {
22     return a.grade<b.grade;
23 }
24 int add(int x,int pos)
25 {
26     while(pos<=N)
27     {
28         vis[pos]+=x;
29         pos+=bit(pos);
30     }
31     return 0;
32 }
33 int sum(int pos)
34 {
35     int sum=0;
36     while(pos>0)
37     {
38         sum+=vis[pos];
39         pos-=bit(pos);
40     }
41     return sum;
42 }
43 int main()
44 {
45     int n;
46    while(cin>>n&&n)
47    {
48        memset(vis,0,sizeof(vis));
49        for(int i=0;i<n;i++)
50        {
51            scanf("%d",&num[i]);
52            nodes[i].grade=num[i];
53            nodes[i].id=i;
54        }
55        sort(nodes,nodes+n,cmp);
56        int ans=500003;
57        for(int i=0;i<n;)
58        {
59            int j;
60            for(j=i;j<n&&(j==i||nodes[j].grade==nodes[j-1].grade);j++)
61            {
62                num[nodes[j].id]=ans;
63            }
64            ans--;
65            i=j;
66        }
67       /* cout<<endl;
68        for(int i=0;i<n;i++)
69        {
70            cout<<num[i]<<endl;
71 
72        }*/
73       // cout<<endl;
74        //ans=0;
75        long long int cnt=0;
76        for(int i=0;i<n;i++)
77        {
78            long long int t=sum(num[i]-1);
79            cnt+=t;
80          //  cout<<t<<" *"<<endl;
81            add(1,num[i]);
82        }
83      //  cout<<endl;
84       // printf("%d\n",ans);
85       cout<<cnt<<endl;
86    }
87    return 0;
88 }
View Code

 

POJ - 2299 - Ultra-QuickSort

标签:题目   style   一个   opened   ace   ref   pen   UI   div   

原文地址:http://www.cnblogs.com/DLKKILL/p/7398332.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!