Skip to content

11258: 【原1258】圣诞树2

题目

题目描述

author: JC 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1258

Description

Dunphy一家制作了很多圣诞树,他们把这些树排成一排。他们发现这些数的高度参差不齐,他们现在希望知道这一排树的“不和谐度”。“不和谐度”指的是一共有多少对树使排在前面的树高于排在后面的树。

例如共有5棵树排成一排,它们的高度分别为5 2 7 2 10,则不和谐度为3。不和谐的3对树是第一棵和第二棵,第一棵和第四棵,第三棵和第四棵。

Input Format

第一行为n,表示共n棵树。 接下来一行有n个不超过100000正整数,依次表示排成一排的每棵树的高度。先输入的排在前面。

有60%的数据n<=1000。 对于100%的数据n<=100000。

Output Format

输出一个正整数k,表示不和谐度。

Sample Input

5
5 2 7 2 10

Sample Output

3

BugenZhao's solution

//
// Created by BugenZhao on 2019/5/16.
//

#ifndef SBL_BMERGESORT_H
#define SBL_BMERGESORT_H

template<typename Item>
class BMergeSort {
public:
    static long long ans;

private:
    static bool less(Item v, Item w) {
        return v < w;
    }

    static void doSort(Item *a, int lo, int hi, Item *aux) {
        if (hi <= lo) return;
        int mid = lo + (hi - lo - 1) / 2;
        doSort(a, lo, mid, aux);
        doSort(a, mid + 1, hi, aux);
        merge(a, lo, mid, hi, aux);
    }

    static void merge(Item *a, int lo, int mid, int hi, Item *aux) {
        for (int i = lo; i <= hi; i++) {
            aux[i] = a[i];
        }
        int i = lo, j = mid + 1;
        for (int k = lo; k <= hi; k++) {
            if (i > mid) a[k] = aux[j++];
            else if (j > hi) a[k] = aux[i++];
                // caution: <=
            else if (!less(aux[j], aux[i])) a[k] = aux[i++];
            else a[k] = aux[j++], ans += mid - i + 1;
        }
    }

public:
    static void sort(Item *a, int n) {
        sort(a, 0, n - 1);
    }

    static void sort(Item *a, int lo, int hi) {
        Item *aux = new Item[hi - lo + 1];
        doSort(a, lo, hi, aux);
        delete[] aux;
    }
};

template<typename Item>
long long BMergeSort<Item>::ans = 0;

#endif //SBL_BMERGESORT_H

#include <iostream>
#include <string>

using std::ios, std::cin, std::cout, std::endl, std::string;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int k;
    cin >> k;
    auto a = new int[k];
    for (int i = 0; i < k; ++i) {
        cin >> a[i];
    }
    BMergeSort<int>::sort(a, k);
    cout << BMergeSort<int>::ans << endl;
    delete[] a;
    return 0;
}

ligongzzz's solution

#include "iostream"
#include "cstdio"
#include "cstring"
#include "cmath"
using namespace std;

class node {
public:
    int val = 0;
    int left = 0, right = 0;
};

int val_data[100009] = { 0 };
node smt[400009];

void build_tree(int l, int r, int root) {
    smt[root].left = l;
    smt[root].right = r;
    if (l == r - 1) {
        smt[root].val = val_data[l];
        return;
    }

    int mid = (l + r) >> 1;
    build_tree(l, mid, root * 2);
    build_tree(mid, r, root * 2 + 1);

    smt[root].val = smt[root * 2].val + smt[root * 2 + 1].val;
}

int query(int l, int r, int root) {
    if (l <= smt[root].left && smt[root].right <= r) {
        return smt[root].val;
    }

    auto mid = (smt[root].left + smt[root].right) >> 1;
    int ans = 0;
    if (l < mid) {
        ans += query(l, r, root * 2);
    }
    if (r > mid) {
        ans += query(l, r, root * 2 + 1);
    }
    return ans;
}

void update(int val,int pos, int root) {
    if (smt[root].right - smt[root].left == 1) {
        smt[root].val += val;
        return;
    }

    auto mid = (smt[root].left + smt[root].right) >> 1;
    if (pos < mid) {
        update(val, pos, root * 2);
    }
    else {
        update(val, pos, root * 2 + 1);
    }
    smt[root].val = smt[root * 2].val + smt[root * 2 + 1].val;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int n;
    cin >> n;

    build_tree(0, 100009, 1);

    long long cnt = 0;
    for (int i = 0; i < n; ++i) {
        cin >> val_data[i];

        update(1, val_data[i], 1);
        cnt += (long long)query(val_data[i] + 1, 100009, 1);
    }

    cout << cnt;

    return 0;
}

Neight99's solution

#include <iostream>

using namespace std;

long long sum = 0, trees[100100], newTrees[100100];
int n;

void cal(int, int);

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int n;

    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> trees[i];
    }

    cal(0, n - 1);

    cout << sum;

    return 0;
}

void cal(int l, int r) {
    int mid = (l + r) / 2;
    int i, j, tmp;

    if (r > l) {
        cal(l, mid);
        cal(mid + 1, r);
        tmp = l;

        for (i = l, j = mid + 1; i <= mid && j <= r;) {
            if (trees[i] > trees[j]) {
                newTrees[tmp++] = trees[j++];
                sum += mid - i + 1;
            } else {
                newTrees[tmp++] = trees[i++];
            }
        }
        if (i <= mid) {
            for (; i <= mid;) {
                newTrees[tmp++] = trees[i++];
            }
        }

        if (j <= r) {
            for (; j <= r;) {
                newTrees[tmp++] = trees[j++];
            }
        }

        for (i = l; i <= r; i++) {
            trees[i] = newTrees[i];
        }
    }
}

skyzh's solution

//
// Created by 3t on 2019/5/16.
//

#include <iostream>

using namespace std;

static int MERGE_TMP[200000];

long long ans = 0;

void merge(int *x, int mid, int N) {
    int i = 0, j = mid;
    int k = 0;
    while (i < mid && j < N) {
        int _x = x[i];
        int _y = x[j];
        if (_x <= _y) {
            MERGE_TMP[k++] = _x;
            i++;
        } else {
            ans += mid - i;
            MERGE_TMP[k++] = _y;
            j++;
        }
    }
    while (i < mid) {
        MERGE_TMP[k++] = x[i++];
    }
    while (j < N) {
        MERGE_TMP[k++] = x[j++];
    }
    for (int i = 0; i < k; i++) {
        x[i] = MERGE_TMP[i];
    }
}

void merge_sort(int *x, int N) {
    if (N == 1) return;
    if (N == 2) {
        if (x[0] > x[1]) {
            ++ans;
            swap(x[0], x[1]);
        }
        return;
    }
    int mid = N / 2;
    merge_sort(x, mid);
    merge_sort(x + mid, N - mid);
    merge(x, mid, N);
}

int X[100000];
int main() {
    int N;
    scanf("%d", &N);
    for (int i = 0; i < N; i++) {
        scanf("%d", &X[i]);
    }
    merge_sort(X, N);
    cout << ans << endl;
    return 0;
}

yyong119's solution

#include <cstdio>
using namespace std;
const int MAX_N = 100010;
long long ans;
int n;
int a[MAX_N];

void merge(int l, int r) {

    int mid = (l + r) >> 1, i = l, j = mid + 1, k = l;
    int tmp[MAX_N];
    while (i <= mid && j <= r) {
        if (a[i] <= a[j]) tmp[k++] = a[i++];
        else {
            ans += mid - i + 1;
            tmp[k++] = a[j++];
        }
    }
    while (i <= mid) tmp[k++] = a[i++];
    while (j <= r) tmp[k++] = a[j++];
    for (int i = l; i <= r; ++i) a[i] = tmp[i];
}

void mergesort(int l, int r) {

    if (l == r) return;
    int mid = (l + r) >> 1;
    mergesort(l, mid);
    mergesort(mid + 1, r);
    merge(l, r);
}

int main() {

    // ios::sync_with_stdio(false);
    // cin >> n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) //cin >> a[i];
        scanf("%d", &a[i]);
    mergesort(1, n);
    // cout << ans << endl;
    printf("%lld\n", ans);
    return 0;
}