QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#421849#7108. Couleurucup-team3215TL 1ms3652kbC++234.9kb2024-05-26 08:25:552024-05-26 08:25:56

Judging History

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

  • [2024-05-26 08:25:56]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:3652kb
  • [2024-05-26 08:25:55]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using pl = pair<ll, ll>;

mt19937 rng{1000 - 7};

struct node {
    int l{-1}, r{-1};
    ll prior{rng()};
    int size{1};
    pl key;

    node(int k) : key({k, prior}) {}
};

vector<node> all;

using pnode = ll;

int size(pnode A) {
    return ~A ? all[A].size : 0;
}

void upd(pnode A) {
    if (!~A)return;
    all[A].size = 1 + size(all[A].l) + size(all[A].r);
}

pnode merge(pnode A, pnode B) {
    if (!~A)return B;
    if (!~B)return A;
    if (all[A].prior > all[B].prior) {
        all[A].r = merge(all[A].r, B);
        upd(A);
        return A;
    } else {
        all[B].l = merge(A, all[B].l);
        upd(B);
        return B;
    }
}

pair<pnode, pnode> split(pnode A, pl key) {
    if (!~A)return {-1, -1};
    if (all[A].key <= key) {
        auto [x, y] = split(all[A].r, key);
        all[A].r = x;
        upd(A);
        upd(y);
        return {A, y};
    } else {
        auto [x, y] = split(all[A].l, key);
        all[A].l = y;
        upd(A);
        upd(x);
        return {x, A};
    }
}

int count(pnode &A, int key) {
    // num <= k
    auto [x, y] = split(A, pl{key,1ll<<37});
    int res = size(x);
    A = merge(x, y);
    return res;
}

pnode insert(pnode &A, pnode B) {
    auto [x, y] = split(A, all[B].key);
    A = merge(x, merge(B, y));
    return A;
}

int add(int key) {
    all.emplace_back(key);
    return all.size() - 1;
}

pnode go(pnode A) {
    if (!~all[A].l && !~all[A].r) {
        return A;
    }
    if (~all[A].r) {
        auto it = go(all[A].r);
        if (it == all[A].r) {
            all[A].r = -1;
        }
        upd(A);
        return it;
    }
    auto it = go(all[A].l);
    if (it == all[A].l) {
        all[A].l = -1;
    }
    upd(A);
    return it;
}

pnode take(pnode &A, int key) {
    auto [x, y] = split(A, pl{key,1ll<<37});
    auto [u, v] = split(x, {key - 1,1ll<<37});
    ll res;
    if (size(v) == 1) {
        res = v;
        v = -1;
    } else {
        res = go(v);
    }
    A = merge(merge(u, v), y);

    return res;
}

struct range {
    ll l, r, who, score;

    auto operator<=>(const range &) const = default;
};

void solve() {
    all.clear();
    int n;
    cin >> n;
    vector<int> a(n);
    for (auto &i: a)cin >> i;
    pnode root = -1;
    multiset<ll> best;
    set<range> ranges;
    ll now{0};
    for (int i = 0; i < n; ++i) {
        int id = add(a[i]);
        insert(root, id);
        now += size(root) - count(root, a[i]);
    }
    ranges.insert({0, n, root, now});
    best.insert(now);
    for (int i = 0; i < n; ++i) {
        if (i)cout << " ";
        ll last = *best.rbegin();
        cout << last;
        ll pos;
        cin >> pos;
        pos ^= last;
        --pos;
//        cout << pos << endl;
        auto it = upper_bound(ranges.begin(), ranges.end(), range{pos, (ll) 1e9 + 7, (ll) 1e9 + 7, (ll) now});
        assert(it != ranges.begin());
        --it;
        auto [l, r, who, score] = *it;
        best.erase(best.find(score));
        ranges.erase(it);
        if (pos - l < r - pos) {
            range left{l, pos, -1, 0};
            range right{pos + 1, r, who, score};
            for (ll j = l; j < pos; ++j) {
                auto it = take(right.who, a[j]);
                insert(left.who, it);
                left.score += size(left.who) - count(left.who, a[j]);
            }
            right.score -= left.score;
            for (ll j = l; j <= pos; ++j) {
                if (j == pos) {
                    auto it = take(right.who, a[j]);
                    it;
                }
                right.score -= count(right.who, a[j] - 1);
            }
            ranges.insert(left);
            best.insert(left.score);
            ranges.insert(right);
            best.insert(right.score);
        } else {
            range left{l, pos, who, score};
            range right{pos + 1, r, -1, 0};
            for (ll j = pos + 1; j < r; ++j) {
                auto it = take(left.who, a[j]);
                insert(right.who, it);
                right.score += size(right.who) - count(right.who, a[j]);
            }
            left.score -= right.score;
            for (ll j = pos; j < r; ++j) {
                if (j == pos) {
                    auto it = take(left.who, a[j]);
                    left.score -= count(right.who, a[j] - 1);
                }
                left.score -= size(left.who) - count(left.who, a[j]);
            }
            ranges.insert(left);
            best.insert(left.score);
            ranges.insert(right);
            best.insert(right.score);
        }
    }
}

int main() {
    cin.tie(0)->sync_with_stdio(false);
    int t;
    cin >> t;
    for (int i = 0; i < t; ++i) {
        if (i)cout << "\n";
        solve();
    }
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3652kb

input:

3
5
4 3 1 1 1
5 4 5 3 1
10
9 7 1 4 7 8 5 7 4 8
21 8 15 5 9 2 4 5 10 6
15
4 8 8 1 12 1 10 14 7 14 2 9 13 10 3
37 19 23 15 7 2 10 15 2 13 4 5 8 7 10

output:

7 0 0 0 0
20 11 7 2 0 0 0 0 0 0
42 31 21 14 14 4 1 1 1 0 0 0 0 0 0

result:

ok 3 lines

Test #2:

score: -100
Time Limit Exceeded

input:

11116
10
10 5 10 3 6 4 8 5 9 8
31 27 24 11 12 3 0 2 3 1
10
8 2 7 2 8 10 1 10 9 10
6 5 2 13 2 1 0 1 3 1
10
7 10 7 6 1 3 10 6 7 9
21 18 10 1 6 5 4 8 9 10
10
2 10 4 8 8 5 7 2 6 7
20 10 9 1 15 0 4 2 9 7
10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
10
1 2 3 4 5 6 7 8 9 10
6 3 5 2 7 10 9 1 4 8
10
1 10 1 3...

output:

21 18 16 12 10 6 4 1 1 0
12 12 10 10 4 4 4 2 1 0
20 16 9 5 3 3 3 0 0 0
22 14 8 8 5 5 2 1 1 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
19 12 7 4 4 2 2 1 0 0
20 18 8 3 1 1 0 0 0 0
45 21 21 10 3 3 3 0 0 0
17 11 8 2 1 1 1 0 0 0
13 4 1 0 0 0 0 0 0 0
29 27 22 15 9 7 4 3 1 0
26 16 9 2 1 1 1 1 1 0
0 0 0 0 0 ...

result: