HDU - 6318 - Swaps and Inversions (reverse logarithm)

Keywords: PHP

HDU - 6318 - Swaps and Inversions

Title:

It can cost x or y to exchange two adjacent elements

Find the minimum cost of eliminating all inverse orders in a sequence

 

Selecting the small and medium cost of xy, eliminating all the reverse pairs is to sort the sequence, and the number of exchanges needed is the reverse logarithm.

The final answer is the inverse logarithm * min (x, y)

 

The inverse logarithm can be obtained by using tree array + discretization or merging sort (because the range of numbers is large, so it should be discretized in tree array).

// Tree array + discretization
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <cmath>

using namespace std;

const int maxn = 1e5 + 10;

int n, x, y, sz;
int a[maxn], Rank[maxn], sum[maxn];

void add(int x){
	for(; x<=n; x += (x&-x)) sum[x] ++;
}

int Sum(int x){
	int ans = 0;
	for(; x>0; x -= (x&-x)) ans += sum[x];
	return ans;
}

int main()
{
	while(scanf("%d%d%d", &n, &x, &y) != EOF){
		sz = 0;
		memset(sum, 0, sizeof sum);
		for(int i=1;i<=n;i++){
			scanf("%d", &a[i]);
			Rank[i] = a[i];
		}
		sort(Rank+1, Rank+1+n);
		sz = unique(Rank+1, Rank+1+n) - Rank - 1;
		long long ans = 0;
		for(int i=1;i<=n;i++){
			int num = lower_bound(Rank+1, Rank+1+sz, a[i]) - Rank;
			add(num);
			ans += i - Sum(num);
		}
		if(x < y) ans = ans * x;
		else ans = ans * y;
		printf("%lld\n", ans);

	}
	return 0;
}
// Merge sort
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

const int maxn = 1e5 + 10;

int n, x, y;
long long ans;
int a[maxn], b[maxn];

void Merge(int l, int mid, int r){
    int p1 = l, p2 = mid + 1;
    int sz = 0;
    while(p1 <= mid && p2 <= r){
        if(a[p1]>a[p2]) ans += mid - p1 + 1, b[++sz] = a[p2++];
        else b[++sz] = a[p1++];
    }
    while(p1 <= mid) b[++sz] = a[p1++];
    while(p2 <= r) b[++sz] = a[p2++];
    for(int i=1;i<=sz;i++) a[l+i-1] = b[i];
}

void merge_sort(int l, int r){
    if(l == r) return;
    int mid = (l+r) >> 1;
    merge_sort(l, mid);
    merge_sort(mid+1, r);
    Merge(l, mid, r);
}

int main()
{
	while(scanf("%d%d%d", &n, &x, &y) != EOF){
		for(int i=1;i<=n;i++) scanf("%d", &a[i]);
		ans = 0;
		merge_sort(1, n);
		if(x < y) ans = ans * x;
		else ans = ans * y;
		printf("%lld\n", ans);
	}
	return 0;
}

 

Posted by allydm on Mon, 04 Feb 2019 11:00:17 -0800