QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#423411 | #7108. Couleur | ucup-team3215 | AC ✓ | 1325ms | 14344kb | C++20 | 4.9kb | 2024-05-28 00:04:42 | 2024-05-28 00:04:43 |
Judging History
answer
#include <algorithm>
#include <array>
#include <iostream>
#include <map>
#include <random>
#include <set>
#include <vector>
using namespace std;
constexpr int N = 1e5;
int ft[N];
void upd(int i, int x, int n) {
for (; i < n; i |= i + 1) ft[i] += x;
}
int que(int i) {
int x{};
for (; i; i &= i - 1) x += ft[i - 1];
return x;
}
struct Node;
struct Ptr {
int i{-1};
Node* operator->();
operator bool() { return ~i; };
};
struct Node {
int x, y, sz;
Ptr l, r;
};
Node nodes[N];
Node* Ptr::operator->() { return nodes + i; }
int sget(Ptr p) { return p? p->sz: 0; }
Ptr upd(Ptr p) { return p->sz = sget(p->l) + sget(p->r) + 1, p; }
Ptr merge(Ptr l, Ptr r) {
if (!l || !r) return l ?: r;
if (l->y < r->y) return l->r = merge(l->r, r), upd(l);
else return r->l = merge(l, r->l), upd(r);
}
Ptr extract(Ptr p, array<int, 2> rb, vector<array<int, 2>>& keys, vector<Ptr>& extracted, int64_t& invs, int ord) {
if (!p || keys.empty() || keys.back() >= rb) return p;
p->l = extract(p->l, array{p->x, p.i}, keys, extracted, invs, ord);
while (p && keys.size() && array{p->x, p.i} == keys.back()) {
invs += ord + sget(p->l);
extracted.push_back(p);
p = merge(p->l, p->r);
keys.pop_back();
if (p) p->l = extract(p->l, array{p->x, p.i}, keys, extracted, invs, ord);
}
return p? p->r = extract(p->r, rb, keys, extracted, invs, ord + sget(p->l) + 1), upd(p): Ptr{};
}
Ptr build(vector<Ptr>& sorted) {
if (sorted.empty()) return {};
vector<Ptr> st{sorted[0]};
sorted[0]->l = {};
for (int i = 1; i < sorted.size(); ++i) {
auto p = sorted[i];
Ptr left;
while (st.size() && st.back()->y > p->y) {
st.back()->r = left;
left = upd(st.back());
st.pop_back();
}
p->l = left;
st.push_back(p);
}
st.back()->r = {};
while (st.size() > 1) {
auto r = st.back();
st.pop_back();
st.back()->r = upd(r);
}
sorted.clear();
return upd(st[0]);
}
int main() {
cin.tie(0)->sync_with_stdio(0);
if (mt19937 rng(23123213); 1)
for (auto& x: nodes) x.y = rng();
for (int tc = (cin >> tc, tc); tc--; ) {
int n; cin >> n;
for (int i = 0; i < n; ++i) cin >> nodes[i].x, nodes[i].sz = 1, ft[i] = 0;
map<int, pair<Ptr, int64_t>> byleft;
multiset<int64_t> costs;
vector<Ptr> tobuild(n);
vector<array<int, 2>> keys;
{
vector<array<int, 2>> sorted(n);
for (int i = 0; i < n; ++i) sorted[i] = {nodes[i].x, i};
sort(sorted.begin(), sorted.end());
for (int i = 0; i < n; ++i) tobuild[i] = {sorted[i][1]};
int64_t cost = 0;
for (int i = n; i--; ) upd(sorted[i][1], 1, n), cost += que(sorted[i][1]);
fill_n(ft, n, 0);
byleft[0] = {build(tobuild), cost};
costs.insert(cost);
}
for(int i = 0; i < n; ++i) {
int64_t mx = *costs.rbegin(), q;
cout << mx << " " + (i == n - 1);
cin >> q; q ^= mx; --q;
auto nit = byleft.upper_bound(q), it = prev(nit);
int l = it->first, r = nit == byleft.end()? n: nit->first;
auto [p, c] = it->second;
byleft.erase(it);
costs.erase(costs.find(c));
if (q - l < r - q) {
int64_t linvs = 0, invs = 0, invs2 = 0;
for (int i = l; i < q; ++i) keys.push_back({nodes[i].x, i});
sort(keys.rbegin(), keys.rend());
for (int i = 0; i < keys.size(); ++i) upd(keys[i][1] - l, 1, q - l), linvs += que(keys[i][1] - l);
fill_n(ft, q - l, 0);
if (l != q) {
p = extract(p, array<int, 2>{N + 1}, keys, tobuild, invs, 0);
byleft[l] = {build(tobuild), linvs};
costs.insert(linvs);
}
keys.push_back({nodes[q].x, q});
p = extract(p, array<int, 2>{N + 1}, keys, tobuild, invs2, 0);
tobuild.clear();
byleft[q] = {};
if (q + 1 != r) {
byleft[q + 1] = {p, c - linvs - invs - invs2};
costs.insert(c - linvs - invs - invs2);
}
} else {
int64_t rinvs = 0, invs = 0, invs2 = 0;
for (int i = q + 1; i < r; ++i) keys.push_back({nodes[i].x, i});
sort(keys.rbegin(), keys.rend());
for (int i = 0; i < keys.size(); ++i) upd(keys[i][1] - q - 1, 1, r - q - 1), rinvs += que(keys[i][1] - q - 1);
fill_n(ft, r - q - 1, 0);
if (q + 1 != r) {
p = extract(p, array<int, 2>{N + 1}, keys, tobuild, invs, 0);
byleft[q + 1] = {build(tobuild), rinvs};
costs.insert(rinvs);
}
keys.push_back({nodes[q].x, q});
p = extract(p, array<int, 2>{N + 1}, keys, tobuild, invs2, 0);
tobuild.clear();
byleft[q] = {};
if (l != q) {
byleft[l] = {p, c - rinvs - ((q + 1 - l) * int64_t(r - q - 1) - invs) - (q - l - invs2)};
costs.insert(c - rinvs - ((q + 1 - l) * int64_t(r - q - 1) - invs) - (q - l - invs2));
}
}
}
cout << '\n';
}
}
这程序好像有点Bug,我给组数据试试?
详细
Test #1:
score: 100
Accepted
time: 2ms
memory: 5612kb
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: 0
Accepted
time: 1325ms
memory: 14344kb
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:
ok 11116 lines
Extra Test:
score: 0
Extra Test Passed