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\n", ans); 43 44 return 0; 45 }