poj 2299 Ultra-QuickSort

题意:

问一个数组从无序到有序需要交换多少次。

思路:

用树状数组,每次求小于等于当前的数字的个数x,这个可以用求前缀和实现,那么容易知道它需要移动的次数就是当前下标i - x。

离散化用map和set各种tle,最终用二分离散化写过了。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <set>
 5 #include <map>
 6 using namespace std;
 7 const int N = 5e5 + 10;
 8 int c[N],b[N];
 9 int a[N];
10 map<int,int> mmp;
11 int cnt;
12 int lowbit(int x)
13 {
14     return x&(-x);
15 }
16 void add(int x,int y)
17 {
18     for (int i = x;i <= cnt;i += lowbit(i)) c[i] += y;
19 }
20 int getsum(int x)
21 {
22     int ans = 0;
23     for (int i = x;i > 0;i -= lowbit(i)) ans += c[i];
24     return ans;
25 }
26 int main()
27 {
28     int n;
29     while (scanf("%d",&n) != EOF && n)
30     {
31         mmp.clear();
32         memset(c,0,sizeof(c));
33         for (int i = 0;i < n;i++)
34         {
35             scanf("%d",&b[i]);
36             //s.insert(b[i]);
37             a[i] = b[i];
38         }
39         sort(a,a+n);
40         int sz = unique(a,a+n) - a;
41         cnt = sz;
42         long long ans = 0;
43         for (int i = 0;i < n;i++)
44         {
45             int gg = lower_bound(a,a+sz,b[i]) - a + 1;
46             //printf("%d*\n",gg);
47             int tmp = getsum(gg);
48             ans += i - tmp;
49             add(gg,1);
50         }
51         printf("%lld\n",ans);
52     }
53     return 0;
54 }

 

posted @ 2018-05-21 20:38  qrfkickit  阅读(170)  评论(0编辑  收藏  举报