逆序对__归并排序__树状数组 Inversions SGU - 180
There are N integers (1<=N<=65537) A1, A2,.. AN (0<=Ai<=10^9). You need to find amount of such pairs (i, j) that 1<=i<j<=N and A[i]>A[j].
Input
Input
The first line of the input contains the number N. The second line contains N numbers A1...AN.
Output
Output
Write amount of such pairs.
Sample test(s)
Input
5
2 3 1 5 4
Output
2 3 1 5 4
Output
3
题目的数据范围有点大,但是可以直接归并排序过了。 如果要用树状数组则需要先离散化。
归并做法:
#include <cstdio> #include <iostream> #include <set> #include <map> #include <stack> #include <queue> #include <cstring> #include <string> #include <sstream> #include <cmath> #include <cstdlib> #include <algorithm> #define sf scanf #define pf printf #define fp(x) freopen((x), "r", stdin) typedef long long ll; using namespace std; const int maxn = 1e5; int qarr[maxn]; ll qans; //long long 不然会over void merge(int arr[], int left, int right, int tarr[]) { if (left>=right) return ; int m = (left + right) >> 1; merge(arr, left, m, tarr); merge(arr, m+1, right, tarr); int i, j, cnt; i = left; j = m + 1; cnt = 0; while (i<=m && j<=right) { if (arr[i] <= arr[j]) tarr[cnt++] = arr[i++]; else { tarr[cnt++] = arr[j++]; qans += (m - i + 1); } } while (i<=m) tarr[cnt++] = arr[i++]; while (j<=right) tarr[cnt++] = arr[j++]; for (i=0; i<cnt; ++i) arr[left++] = tarr[i]; } void mergesort(int arr[], int left, int right) { int *p = new int[right-left+1]; merge(arr, left, right, p); } int main() { int n; sf("%d", &n); for (int i=1; i<=n; ++i) sf("%d", &qarr[i]); mergesort(qarr, 1, n); cout << qans << endl; return 0; }
树状数组做法:
#include <cstdio> #include <iostream> #include <set> #include <map> #include <stack> #include <queue> #include <cstring> #include <string> #include <sstream> #include <cmath> #include <cstdlib> #include <algorithm> #define sf scanf #define pf printf #define fp(x) freopen((x), "r", stdin) typedef long long ll; using namespace std; const int maxn = 1e5; struct nobe{ int id; int val; int ls; bool operator < (const nobe &a) const { if (val != a.val) return val < a.val; return id < a.id; } }te[maxn]; int qsum[maxn]; ll qans; bool cmp(const nobe &a, const nobe &b) { return a.id < b.id; } inline int lowbit(int id) { return id&-id; } int update(int id, int _maxn) { while (id <= _maxn) { qsum[id] += 1; id+=lowbit(id); } } int getsum(int id) { int res = 0; while (id) { res += qsum[id]; id -= lowbit(id); } return res; } int main() { int n; sf("%d", &n); for (int i=1; i<=n; ++i) { sf("%d", &te[i].val); te[i].id = i; } sort(te+1, te+1+n); int lst = te[1].val; int cnt = 1; for (int i=1; i<=n; ++i) te[i].val = i; sort(te+1, te+1+n, cmp); for (int i=1; i<=n; ++i) { update(te[i].val, n); qans += i - 1 - getsum(te[i].val-1); } cout << qans << endl; return 0; }