QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#200228#5143. Quick SortbigJTL 41ms3632kbC++204.8kb2023-10-04 15:54:072023-10-04 15:54:07

Judging History

你现在查看的是最新测评结果

  • [2023-10-04 15:54:07]
  • 评测
  • 测评结果:TL
  • 用时:41ms
  • 内存:3632kb
  • [2023-10-04 15:54:07]
  • 提交

answer

#include <bits/stdc++.h>

template<typename T, std::size_t N> std::istream& operator>>(std::istream& is, std::array<T, N>& v) { for (auto& i : v) is >> i; return is; }
template<typename T, std::size_t N> std::ostream& operator<<(std::ostream& os, std::array<T, N>& v) { for (auto& i : v) os << i << ' '; return os; }
template<typename T> std::istream& operator>>(std::istream& is, std::vector<T>& v) { for (auto& i : v) is >> i; return is; }
template<typename T> std::ostream& operator<<(std::ostream& os, std::vector<T>& v) { for (auto& i : v) os << i << ' '; return os; }
template<typename...Args> void debug(Args...args) { ((std::cerr << args << ' '), ...); std::cerr << '\n'; }
template<typename...Args> void println(Args...args) { ((std::cout << args << ' '), ...); std::cout << '\n'; }

using i64 = long long;

template <class Info>
struct SegmentTree {
#define m (l + r) / 2
    int n;
    std::vector<Info> tr;
    SegmentTree() : n(0) {}
    SegmentTree(int n_, Info v_ = Info()) {
        init(n_, v_);
    }
    template<class T>
    SegmentTree(std::vector<T> init_) {
        init(init_);
    }
    void init(int n_, Info v_ = Info()) {
        init(std::vector(n_, v_));
    }
    template<class T>
    void init(std::vector<T> init_) {
        n = init_.size();
        tr.assign(4 << std::__lg(n), Info());
        std::function<void(int, int, int)> build = [&](int p, int l, int r) {
            if (r - l == 1) {
                tr[p] = { init_[l] };
                return;
            }
            build(2 * p, l, m);
            build(2 * p + 1, m, r);
            pull(p);
        };
        build(1, 0, n);
    }

    void pull(int p) {
        tr[p] = tr[2 * p] + tr[2 * p + 1];
    }

    void modify(int p, int l, int r, int x, const Info& v) {
        if (r - l == 1) {
            tr[p] = v;
            return;
        }
        if (x < m) {
            modify(2 * p, l, m, x, v);
        }
        else {
            modify(2 * p + 1, m, r, x, v);
        }
        pull(p);
    }
    void modify(int x, const Info& v) {
        modify(1, 0, n, x, v);
    }

    int findRightUpper(int p, int l, int r, int x, int v) { // 向右找第一个不小于v的值
        if (tr[p].mx < v) {
            return -1;
        }
        if (r - l == 1) {
            return l;
        }
        if (x >= m) {
            return findRightUpper(2 * p + 1, m, r, x, v);
        }
        int ret = findRightUpper(2 * p, l, m, x, v);
        if (ret != -1) {
            return ret;
        }
        return findRightUpper(2 * p + 1, m, r, x, v);
    }

    int findLeftLower(int p, int l, int r, int x, int v) { //向左找第一个不大于v的值
        if (tr[p].mn > v) {
            return -1;
        }
        if (r - l == 1) {
            return l;
        }
        if (x < m) {
            return findLeftLower(2 * p, l, m, x, v);
        }
        int ret = findLeftLower(2 * p + 1, m, r, x, v);
        if (ret != -1) {
            return ret;
        }
        return findLeftLower(2 * p, l, m, x, v);
    }

    int findRightUpper(int x, int v) {
        return findRightUpper(1, 0, n, x, v);
    }
    int findLeftLower(int x, int v) {
        return findLeftLower(1, 0, n, x, v);
    }

#undef m
};

struct Info {
    int mx, mn;
    Info(int x) :mx(x), mn(x) {}
    Info() :mx(-1e9), mn(1e9) {}
    Info(int mx, int mn) :mx(mx), mn(mn) {}
    friend Info operator+(const Info& a, const Info& b) {
        return Info(std::max(a.mx, b.mx), std::min(a.mn, b.mn));
    }
};

SegmentTree<Info> seg;

int res = 0;

int work(std::vector<int>& a, int l, int r) {
    int m = a[(l + r) / 2];
    int i = l - 1, j = r + 1;
    while (true) {
        i++, j--;
        if (j - i + 1 <= 10) {
            while (a[i] < m) i++;
            while (a[j] > m) j--;
        }
        else {
            std::tie(i, j) = std::pair(seg.findLeftLower(i, m), seg.findRightUpper(j, m));
        }

        if (i >= j) {
            return j;
        }
        seg.modify(i, a[j]);
        seg.modify(j, a[i]);
        std::swap(a[i], a[j]);
        res++;
    }
    return -1;
}

void quickSort(std::vector<int>& a, int l, int r) {
    if (l >= 0 && r >= 0 && l < r) {
        int m = work(a, l, r);
        quickSort(a, l, m);
        quickSort(a, m + 1, r);
    }
}

auto solve() {
    int n;
    std::cin >> n;

    std::vector<int> a(n + 1);
    for (int i = 1; i <= n; i++) {
        std::cin >> a[i];
    }

    seg.init(a);

    quickSort(a, 1, n);
    std::cout << res << "\n";
}

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

    int c = 1;
    std::cin >> c;

    for (int i = 1; i <= c; i++) {
        res = 0;
        solve();
    }

    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 3496kb

input:

3
3
3 2 1
5
2 4 5 3 1
10
7 2 4 6 1 9 10 8 5 3

output:

1
4
7

result:

ok 3 number(s): "1 4 7"

Test #2:

score: 0
Accepted
time: 40ms
memory: 3608kb

input:

100000
4
3 4 2 1
5
5 4 1 3 2
4
3 1 4 2
4
4 2 1 3
4
1 3 2 4
4
4 2 3 1
4
3 2 1 4
5
1 2 3 4 5
5
5 2 3 1 4
5
1 3 5 4 2
5
4 3 2 1 5
5
3 4 2 1 5
5
5 4 3 2 1
4
3 4 2 1
5
4 2 5 1 3
5
4 1 5 2 3
4
3 4 1 2
4
2 1 3 4
5
4 3 2 5 1
4
4 2 1 3
5
3 1 5 2 4
4
4 1 2 3
5
1 5 2 4 3
5
4 1 3 5 2
5
4 2 3 5 1
5
1 2 3 4 5
5
4...

output:

3
4
3
2
1
1
1
0
2
2
2
3
2
3
2
3
2
1
3
2
4
3
2
3
2
0
4
2
4
1
3
2
3
2
2
1
3
1
1
2
4
3
2
3
1
1
1
3
3
3
4
4
2
3
3
2
3
3
3
2
1
1
2
3
1
3
1
1
3
4
2
2
4
1
1
3
2
2
2
2
1
3
4
4
3
4
2
2
1
3
2
3
2
3
3
2
1
4
2
3
4
1
2
2
3
2
2
3
2
2
2
2
4
1
2
3
2
2
2
2
3
2
3
4
3
2
3
4
2
4
1
3
2
3
4
3
3
4
1
2
4
3
2
4
2
3
3
1
2
2
...

result:

ok 100000 numbers

Test #3:

score: 0
Accepted
time: 41ms
memory: 3632kb

input:

50000
10
3 1 2 10 6 8 5 4 7 9
10
8 3 9 2 10 4 5 1 7 6
9
6 8 4 9 5 7 1 3 2
9
6 7 9 3 8 5 2 1 4
10
7 10 1 2 6 5 3 9 4 8
10
1 10 4 3 2 9 7 8 5 6
9
1 5 3 4 9 6 7 2 8
10
4 7 2 8 3 6 9 5 10 1
9
6 4 9 1 8 5 2 3 7
10
5 1 7 8 10 3 9 6 2 4
9
4 8 6 3 9 7 5 2 1
9
9 1 7 6 2 3 8 5 4
10
5 7 2 1 4 3 6 8 9 10
10
9 7...

output:

8
8
8
8
9
5
3
8
8
9
9
8
7
9
8
9
6
8
8
7
7
11
7
6
9
8
3
6
8
8
6
7
8
4
8
6
6
8
5
6
7
6
7
5
5
6
9
5
9
10
6
7
8
9
4
9
6
7
8
8
9
9
5
7
6
6
10
9
8
6
4
8
6
10
4
9
9
6
9
6
7
7
7
9
6
6
9
8
7
11
9
5
6
8
8
8
8
8
6
4
8
8
5
8
8
8
9
8
8
7
8
7
6
10
9
7
7
7
6
5
5
6
8
9
5
6
7
8
6
7
9
6
7
9
7
7
6
8
9
9
7
7
9
7
8
6
7
...

result:

ok 50000 numbers

Test #4:

score: -100
Time Limit Exceeded

input:

5000
94
69 86 59 9 67 89 24 63 14 18 16 11 19 46 23 40 4 55 53 61 30 3 78 29 15 74 32 41 51 13 77 47 66 92 57 45 42 21 62 43 26 1 84 75 71 54 73 36 39 48 88 8 80 64 58 10 60 76 17 70 25 37 38 6 72 91 7 20 68 2 35 44 90 79 50 93 81 94 27 33 5 52 28 82 56 87 31 22 83 34 65 85 49 12
97
44 97 28 56 95 6...

output:


result: