QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#199379#5143. Quick SortbigJWA 95ms3544kbC++205.2kb2023-10-04 10:51:002023-10-04 10:51:00

Judging History

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

  • [2023-10-04 10:51:00]
  • 评测
  • 测评结果:WA
  • 用时:95ms
  • 内存:3544kb
  • [2023-10-04 10:51:00]
  • 提交

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);
    }

    Info rangeQuery(int p, int l, int r, int x, int y) {
        if (l >= y || r <= x) {
            return Info();
        }
        if (l >= x && r <= y) {
            return tr[p];
        }
        return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
    }
    Info rangeQuery(int l, int r) {
        return rangeQuery(1, 0, n, l, r);
    }

    int findFirstUpper(int p, int l, int r, int x, int y, int v) {
        if (r - l == 1) {
            return l;
        }
        int mid = m - 1;
        if (x > mid) {
            return findFirstUpper(2 * p + 1, m, r, x, y, v);
        }
        else if (y < mid) {
            return findFirstUpper(2 * p, l, m, x, y, v);
        }
        if (rangeQuery(x, mid + 1).mx < v) {
            return findFirstUpper(2 * p + 1, m, r, mid, y, v);
        }
        return findFirstUpper(2 * p, l, m, x, mid + 1, v);
    }

    int findFirstLower(int p, int l, int r, int x, int y, int v) {
        if (r - l == 1) {
            return l;
        }
        int mid = m - 1;
        if (x > mid) {
            return findFirstLower(2 * p + 1, m, r, x, y, v);
        }
        else if (y < mid) {
            return findFirstLower(2 * p, l, m, x, y, v);
        }
        if (rangeQuery(mid, y).mn > v) {
            return findFirstLower(2 * p, l, m, x, y, v);
        }
        return findFirstLower(2 * p + 1, m, r, x, y, v);
    }

    int findFirstUpper(int l, int r, int v) {
        return findFirstUpper(1, 0, n, l, r, v);
    }
    int findFirstLower(int l, int r, int v) {
        return findFirstLower(1, 0, n, l, r, 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--;
        std::tie(i, j) = std::pair(seg.findFirstUpper(i, j + 1, m), seg.findFirstLower(i, j + 1, m));
        while (a[j] > m) j--;

        if (i >= j) {
            return j;
        }
        else {
            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: 3504kb

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: 69ms
memory: 3544kb

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: -100
Wrong Answer
time: 95ms
memory: 3512kb

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
7
8
7
9
8
11
6
8
8
7
7
11
7
6
11
8
3
6
8
6
6
7
10
4
8
6
6
8
5
6
7
6
7
5
5
8
9
5
9
10
6
7
8
9
4
9
6
7
8
8
9
7
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
9
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
5
7
7
6
5
5
6
8
9
5
6
7
8
6
7
9
6
9
9
7
7
6
8
9
9
7
7
9
7
8
6
...

result:

wrong answer 11th numbers differ - expected: '9', found: '7'