zoj 4046

相邻的两个才能交换,很容易就能想到逆序对。求完逆序数后,分析下,序列可以看成两段,分界线是1和5,所以可以枚举1的位置,取最小就可以了 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int mx = 1e5+10;
 5 int a[mx], b[mx], c[mx], pos[mx];
 6 int n;
 7 inline int lowbit(int x){
 8     return x&(-x);
 9 }
10 inline void add(int x, int v){
11     while(x <= n){
12         c[x] += v;
13         x += lowbit(x);
14     }
15 }
16 inline int query(int x){
17     int ans = 0;
18     while(x>0){
19         ans += c[x];
20         x -= lowbit(x);
21     }
22     return ans;
23 }
24 int main(){
25     int t;
26     scanf("%d", &t);
27     while(t--){
28         memset(c, 0, sizeof(c));
29         scanf("%d", &n);
30         ll cnt = 0;
31         for(int i = 1; i <= n; i++){
32             scanf("%d", &a[i]);
33             add(a[i], 1);
34             pos[a[i]] = i;
35             b[i] = i-query(a[i]);
36             cnt += b[i];
37         }
38         ll ans = cnt;
39         for(int i = n; i > 1; i--){
40             cnt += 2ll*pos[i]-n-1;
41             ans = min(ans, cnt);
42         }
43         printf("%lld\n", ans);
44     }
45     return 0;
46 }
View Code

猜你喜欢

转载自www.cnblogs.com/ballballyounoA/p/9977648.html
ZOJ