Submission #408959

#TimeUsernameProblemLanguageResultExecution timeMemory
408959Tc14Arranging Shoes (IOI19_shoes)C++17
100 / 100
286 ms23244 KiB
//#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#include "shoes.h"
using namespace std;
#define ve vector
typedef long long ll;
typedef pair<int, int> pii;
const int INF = 1e9 + 10;

struct SegmentTree {

    int Cap;
    ve<int> Seg;

    int left(int x) { return 2 * x; }
    int right(int x) { return 2 * x + 1; }
    int parent(int x) { return x / 2; }

    void build(int a) {
        Cap = 1 << (int)ceil(log2(a));
        Seg = ve<int>(2 * Cap);
    }

    int query(int a, int b) {
        return query(a, b, 0, Cap - 1, 1);
    }

    int query(int a, int b, int i, int j, int curr) {

        if (a <= i && j <= b) return Seg[curr];
        if (b < i || j < a) return 0;

        int m = (i + j) / 2;
        return query(a, b, i, m, left(curr)) + query(a, b, m + 1, j, right(curr));
    }

    void update(int p) {

        Seg[Cap + p] = 1;
        int curr = parent(Cap + p);

        while (curr != 0) {
            Seg[curr] = Seg[left(curr)] + Seg[right(curr)];
            curr = parent(curr);
        }
    }

};

ll count_swaps(ve<int> S) {

    int n;
    ve<int> A;
    ve<pii> F;
    map<int, pair<ve<int>, ve<int>>> M;
    SegmentTree Seg;

    n = (int)S.size() / 2;
    A = ve<int>(2 * n);
    F = ve<pii>(2 * n, {-1, -1});

    for (int i = 0; i < 2 * n; i++) {
        int s = S[i];
        if (s < 0) M[-s].first.push_back(i);
        else M[s].second.push_back(i);
    }

    for (auto x : M) {
        int l = (int)x.second.first.size();
        for (int i = 0; i < l; i++) {
            int a = x.second.first[i];
            int b = x.second.second[i];
            F[min(a, b)] = {a, b};
        }
    }

    int cnt = 0;
    for (int i = 0; i < 2 * n; i++) {
        int a, b;
        tie(a, b) = F[i];
        if (a != -1) {
            A[a] = cnt;
            A[b] = cnt + 1;
            cnt += 2;
        }
    }

    ll ans = 0;
    Seg.build(2 * n);

    for (int i = 0; i < 2 * n; i++) {
        ans += Seg.query(A[i], 2 * n - 1);
        Seg.update(A[i]);
    }

    return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...