题意:
问一个数组从无序到有序需要交换多少次。
思路:
用树状数组,每次求小于等于当前的数字的个数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* ",gg); 47 int tmp = getsum(gg); 48 ans += i - tmp; 49 add(gg,1); 50 } 51 printf("%lld ",ans); 52 } 53 return 0; 54 }