let menu = ["Home", "Algorithms", "CodeHub", "VNOI Statistics"];

Overview

NKINV - Dãy nghịch thế

solution.md

Gọi C[x]C[x] là số lượng giá trị xx đã xuất hiện. Duyệt các phần tử từ đầu dãy đến cuối dãy, mối lần duyệt ta tính tổng từ C[x+1]C[x+1] đến cuối mảng CC rồi thêm vào kết quả, sau đó tăng C[x]C[x] (xx là phần tử đang xét).

Để AC cần sử dụng cấu trúc Fenwick Tree để giảm độ phức tạp của phương pháp trên xuống còn O(NlogC)O(NlogC).

Lưu ý là ta cần tính tổng từ một vị trí đến cuỗi dãy, ngược lại với phiên bản trong bài viết trên.

main.cpp
Open in Github Download
#include <iostream>
#include <vector>
using namespace std;

#define LL long long

struct Fenwick {
    int n;
    vector<LL> f;
    Fenwick(int n): n(n), f(n+1, 0) {}
    void set(int i) {
        for (; i>=1; i -= i&(-i)) f[i]++;
    }
    LL get(int i) {
        LL result = 0;
        for (; i<=n; i += i&(-i)) result += f[i];
        return result;
    }
};

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

    int n; cin >> n;
    Fenwick f(60000);
    LL result = 0;
    while (n--) {
        LL x; cin >> x;
        result += f.get(x+1);
        f.set(x);
    }
    cout << result;

    return 0;
}
Comments