QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#407589 | #2296. Exchange Students | Andycipation | WA | 1ms | 3596kb | C++20 | 3.3kb | 2024-05-09 02:24:21 | 2024-05-09 02:24:23 |
Judging History
answer
/*
* author: ADMathNoob
* created: 05/08/24 14:04:52
* problem: https://qoj.ac/problem/2296
*/
/*
Comments about problem:
*/
#include <bits/stdc++.h>
using namespace std;
#ifdef _DEBUG
#include "debug.h"
#else
#define debug(...) 42
#endif
template <typename T>
class Fenwick {
public:
const int n;
const int max_power; // smallest power of 2 larger than n
vector<T> tree;
Fenwick(int _n) : n(_n), max_power(1 << (32 - __builtin_clz(n))), tree(n) {
assert(n > 0);
}
T get(int x) const {
assert(-1 <= x && x < n);
T res{};
while (x >= 0) {
res += tree[x];
x = (x & (x + 1)) - 1;
}
return res;
}
void modify(int x, T v) {
assert(0 <= x && x < n);
while (x < n) {
tree[x] += v;
x |= (x + 1);
}
}
/*
returns the first index p such that sum(a[0..p]) >= t
returns -1 if the empty sum works and n if no sum works
NOTE: it only makes sense to use this function when all values
in the array we are maintaining are non-negative;
this method allows such queries in O(log(n)) instead of O(log^2(n))
*/
int lower_bound(T t) const {
if (t <= 0) {
return -1;
}
int k = -1;
T sum = 0;
for (int p = max_power; p > 0; p >>= 1) {
if (k + p < n && sum + tree[k + p] < t) {
k += p;
sum += tree[k];
}
}
return k + 1;
}
};
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
map<int, vector<int>> pos1;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
pos1[x].push_back(i);
}
map<int, vector<int>> pos2;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
pos2[x].push_back(i);
}
Fenwick<int> ft1(n), ft2(n);
set<int> alive;
for (int i = 0; i < n; i++) {
ft1.modify(i, +1);
ft2.modify(i, +1);
alive.insert(i);
}
vector<pair<int, int>> ops;
const int OPS = 200000;
long long ans = 0;
for (auto [h, st] : pos1) {
auto fin = pos2[h];
int k = st.size();
for (int z = 0; z < k; z++) {
ans += abs(ft2.get(fin[z]) - ft1.get(st[z]));
}
set<int> goL, goR;
for (int z = 0; z < k; z++) {
if (ft1.get(st[z]) > ft2.get(fin[z])) {
goL.insert(z);
}
if (ft1.get(st[z]) < ft2.get(fin[z])) {
goR.insert(z);
}
}
for (int z = 0; z < k; z++) {
ft1.modify(st[z], -1);
ft2.modify(fin[z], -1);
}
while ((int) ops.size() < OPS && (!goL.empty() || !goR.empty())) {
if (!goL.empty()) {
int z = *goL.begin();
goL.erase(goL.begin());
auto jt = alive.find(st[z]);
--jt;
ops.emplace_back(st[z], *jt);
st[z] = *jt;
if (*jt != fin[z]) {
goL.insert(z);
}
} else {
int z = *prev(goR.end());
goR.erase(prev(goR.end()));
auto jt = alive.find(st[z]);
++jt;
ops.emplace_back(st[z], *jt);
st[z] = *jt;
if (*jt != fin[z]) {
goR.insert(z);
}
}
}
for (int i : fin) {
alive.erase(i);
}
}
cout << ans << '\n';
for (auto [x, y] : ops) {
cout << x + 1 << ' ' << y + 1 << '\n';
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3536kb
input:
1 279122803 279122803
output:
0
result:
ok good
Test #2:
score: 0
Accepted
time: 0ms
memory: 3532kb
input:
2 212545283 896408766 212545283 896408766
output:
0
result:
ok good
Test #3:
score: 0
Accepted
time: 1ms
memory: 3592kb
input:
4 3 1 2 4 4 2 1 3
output:
2 2 3 1 4
result:
ok good
Test #4:
score: -100
Wrong Answer
time: 1ms
memory: 3596kb
input:
6 5 1 2 3 4 6 6 4 3 2 1 5
output:
7 2 3 3 4 4 5 3 4 4 3 1 6
result:
wrong output format Unexpected end of file - int32 expected