CodeVs1688 求逆序对

题目大意就是求一个序列中逆序对的数目, 由于Luogu的数据太弱导致错误的程序竟然通过了, 于是我在CodeVs上评测的程序

输入格式:

第一行,一个数n,表示序列中有n个数。

第二行n个数,表示给定的序列。

输出格式:

给定序列中逆序对的数目。

输入样例#1:
6
5 4 2 6 3 1
输出样例#1:
11

第一种方法是用归并排序求逆序对

 1 //2017年8月21日17:26:42
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int maxn = 100001;
 8 int a[maxn];
 9 int temp[maxn];
10 int n;
11 int ans;
12 
13 void merge_sort(int i, int j){
14     if(i == j)
15         return;
16     int mid = (i+j)/2;
17     merge_sort(i, mid);
18     merge_sort(mid+1, j);
19     int l=i, r=mid+1, k=i;
20     for(; k<=j; k++){
21         if(l > mid){
22             temp[k] = a[r];
23             r++;
24         }else if(r > j){
25             temp[k] = a[l];
26             l++;
27         }else if(a[l] <= a[r]){
28             temp[k] = a[l];
29             l++;
30         }else if(a[l] > a[r]){
31             temp[k] = a[r];
32             r++;
33             ans = ans+mid-l+1;
34         }
35     }
36     for(int k=i;k<=j;k++)
37         a[k] = temp[k];
38 }
39 
40 
41 
42 
43 int main(){
44     cin >> n;
45     for(int i=1;i<=n;i++)
46         cin >> a[i];
47     merge_sort(1, n); 
48     
49     cout << ans;
50 
51     return 0;
52 }
53 
54     //暴力解法 
55         /*
56     for(int i=1;i<=n;i++)
57         for(int j=1;j<=n;j++){
58             if(i > j){
59                 if(a[i] < a[j]){
60                     ans++;
61                 }
62             }
63         }
64     
65     cout << ans;
66     */

 第二种方法, 树状数组求逆序对, 需要离散化

 1 //2018年2月19日23:02:21 
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int N = 1000001;
 8 int n, a[N], b[N], c[N];
 9 long long ans;
10 
11 inline int read(){
12     int x=0, f=1; char ch = getchar();
13     while(ch<'0' || ch>'9'){if(ch == '-') f=-1; ch = getchar();}
14     while(ch>='0' && ch<='9'){ x = x*10+ch-'0'; ch = getchar();}
15     return x*f;
16 }
17 
18 int lowbit(int x){
19     return x & (-x);
20 }
21 void add(int x, int k){
22     for(int i=x; i<=n; i+=lowbit(i)) c[i] += k; 
23 }
24 
25 int sum(int x){
26     int res = 0;
27     for(int i=x; i; i-=lowbit(i)) res += c[i];
28     return res;
29 }
30 
31 int main(){
32     n = read();
33     for(int i=1;i<=n;i++)
34         a[i] = b[i] = read();
35     sort(b+1, b+n+1);
36     for(int i=1;i<=n;i++)
37         a[i] = lower_bound(b+1, b+n+1, a[i]) - b;
38     for(int i=n; i; i--){
39         ans += sum(a[i]-1); //注意这里不是ans += sum(a[i]); //故意写成这样Luogu还AC了... 
40         add(a[i], 1);
41     }
42     printf("%lld
", ans);
43     
44     return 0;
45 }
原文地址:https://www.cnblogs.com/sineagle/p/8454539.html