One day an algorithm problem - reverse order (merge sort, Fenwick tree, discrete)

[Title] to reverse: https://www.luogu.com.cn/problem/P1908

Solution one: Violence Act for n relatively small, this question does not apply.

Solution two: merge sort.

We can easily come to find in the reverse order of the merge operation time.

I note pointing to the left region of the current node, j points to the right of the current node region.

When a [i] <= a [j], a [i] is greater than or equal to the right area a [j] does not constitute any number of reverse order, just like i ++.

When all data a [i]> a [j] when, a [j] is greater than or equal to the left area a [i] are configured in reverse order, so the number of reverse + = mid-l + 1

Because int overflow, so the sum spent long long

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #define N 500010
 5 using namespace std;
 6 
 7 int n, a[N],c[N];
 8 long long sum=0;
 9 void mergeSort(int l, int r) {
10     if (l >= r)return;
11     int mid = (l + r) >> 1,k = mid + 1, t = l, left = l, right = r;
12     mergeSort(l, mid);
13     mergeSort(mid + 1, r);
14     while (l <= mid && k <= r) {
15         if (a[l] <= a[k]) {
16             c[t++] = a[l++];
17         }
18         else
19             c[t++] = a[k++], sum += (long long)mid - l + 1;
20     }
21     while (l <= mid)
22         c[t++] = a[l++];
23     while (k <= r)
24         c[t++] = a[k++];
25     for (; left <= right; left++)
26         a[left] = c[left];
27 }
28 
29 int main() {
30     scanf("%d", &n);
31     for (int i = 1; i <= n; i++)
32         scanf("%d", &a[i]);
33     mergeSort(1, n);
34     printf("%lld", sum);
35     return 0;
36 }

∠ (° ゝ °)!

Solution three: Fenwick tree

Referred to a [i] is the original array

Then we each a [i] position in Fenwick tree tree [] in correspondence are +1, so a [i] prefix and represents the small than or equal to its number, then the i- prefix and is reverse for a number.

Then ...... overflow.

Because each number in the sequence does not exceed 10 ^ 9, so, you know.

In order to reduce space consumption, we use discrete.

Will be a sort, and each number in place of 1 ...... n respectively, so that the size of the tree only needs << 2 10 ^ 5, greatly reducing consumption.

code show as below:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<stdio.h>
 4 #define N 500010
 5 #define lowbit(x) x&-x
 6 typedef long long ll;
 7 using namespace std;
 8 
 9 int n, b[N],tree[N<<2];
10 struct node {
11     int val, num;
12 } a[N];
13 
14 //inline作用和define差不多
15 inline bool cmp(node a, node b) {
16     if (a.val == b.val)return a.num < b.num;
17     return a.val < b.val;
18 }
19 void insert(int x, int k) {
20     while (x <= n) {
21         tree[x] += k;
22         x += lowbit(x);
23     }
24 }
25 ll query(int x) {
26     ll ans = 0;
27     while (x) {
28         ans +=Tree [X];
 29          X - = lowbit (X);
 30      }
 31 is      return ANS;
 32  }
 33 is  
34 is  int main () {
 35      Scanf ( " % D " , & n-);
 36      for ( int I = . 1 ; I <= n-; I ++ )
 37 [          Scanf ( " % D " , A & [I] .val), A [I] .num = I;
 38 is      // discretization, too prevent some number, derived overflow space 
39      Sort (A + . 1 , + n-A + . 1 , CMP);
 40     for (int i = 1; i <= n; i++)
41         b[a[i].num] = i;
42     ll ans=0;
43     for (int i = 1; i <= n; i++) {
44         insert(b[i], 1);
45         ans += i-query(b[i]);
46     }
47     printf("%lld", ans);
48     return 0;
49 }

 

Guess you like

Origin www.cnblogs.com/zyyz1126/p/12611742.html