QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#61313 | #2555. Two Bullets | alpha1022 | WA | 3ms | 3816kb | C++14 | 4.3kb | 2022-11-12 09:30:21 | 2022-11-12 09:30:23 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 1e5;
int n, p[N + 5], q[N + 5];
int level[N + 5];
int a[N + 5], b[N + 5];
struct BinaryIndexedTree {
int c[N + 5];
void update(int x, int k) {
for (; x <= n; x += x & -x) c[x] = max(c[x], k);
}
int query(int x) {
int ret = 0;
for (; x; x &= x - 1) ret = max(ret, c[x]);
return ret;
}
} bit;
struct TreeOfTree {
struct segnode {
int max;
int ls, rs;
} seg[N * 80 + 5];
void insert(int x, int k, int &u, int tl, int tr) {
static int tot = 0;
if (!u) u = ++tot;
seg[u].max = max(seg[u].max, k);
if (tl == tr) return ;
int mid = (tl + tr) >> 1;
if (x <= mid) insert(x, k, seg[u].ls, tl, mid);
else insert(x, k, seg[u].rs, mid + 1, tr);
}
int query(int l, int r, int u, int tl, int tr) {
if (!u || (l <= tl && tr <= r)) return seg[u].max;
int mid = (tl + tr) >> 1;
int ret = 0;
if (l <= mid) ret = max(ret, query(l, r, seg[u].ls, tl, mid));
if (r > mid) ret = max(ret, query(l, r, seg[u].rs, mid + 1, tr));
return ret;
}
#define ls (u << 1)
#define rs (ls | 1)
int rt[N * 4 + 5];
void insert(int x, int y, int k, int u, int tl, int tr) {
insert(y, k, rt[u], 1, n);
if (tl == tr) return ;
int mid = (tl + tr) >> 1;
if (x <= mid) insert(x, y, k, ls, tl, mid);
else insert(x, y, k, rs, mid + 1, tr);
}
void insert(int x, int y, int k) { insert(x, y, k, 1, 1, n); }
int query(int l, int r, int x, int y, int u, int tl, int tr) {
if (l <= tl && tr <= r) return query(x, y, rt[u], 1, n);
int mid = (tl + tr) >> 1;
int ret = 0;
if (l <= mid) ret = max(ret, query(l, r, x, y, ls, tl, mid));
if (r > mid) ret = max(ret, query(l, r, x, y, rs, mid + 1, tr));
return ret;
}
int query(int l, int r, int x, int y) { return l <= r && x <= y ? query(l, r, x, y, 1, 1, n) : 0; }
#undef ls
#undef rs
} tr;
struct SegmentTree {
#define ls (u << 1)
#define rs (ls | 1)
struct node {
int min;
bool vis;
} seg[N * 4 + 5];
void build(int u, int tl, int tr) {
if (tl == tr) { seg[u].min = p[tl]; return ; }
int mid = (tl + tr) >> 1;
build(ls, tl, mid), build(rs, mid + 1, tr);
seg[u].min = min(seg[ls].min, seg[rs].min);
}
void build() { build(1, 1, n); }
void erase(int x, int u, int tl, int tr) {
seg[u].vis = 0;
if (tl == tr) { seg[u].min = inf; return ; }
int mid = (tl + tr) >> 1;
if (x <= mid) erase(x, ls, tl, mid);
else erase(x, rs, mid + 1, tr);
seg[u].min = min(seg[ls].min, seg[rs].min);
}
void erase(int x) { erase(x, 1, 1, n); }
void search(vector<int> &ret, int rmin, int u, int tl, int tr) {
if (seg[u].min >= rmin || seg[u].vis) return ;
seg[u].vis = 1;
if (tl == tr) { ret.push_back(tl); return ; }
int mid = (tl + tr) >> 1;
search(ret, rmin, rs, mid + 1, tr), search(ret, min(rmin, seg[rs].min), ls, tl, mid);
}
vector<int> search() {
vector<int> ret;
search(ret, inf, 1, 1, n);
return ret;
}
#undef ls
#undef rs
} seg;
vector<pair<int, int>> ans;
priority_queue<int> que;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%d", p + i), q[p[i]] = i;
for (int i = n; i; --i)
bit.update(p[i], (level[i] = bit.query(p[i] - 1)) + 1);
iota(a + 1, a + n + 1, 1), sort(a + 1, a + n + 1, [](int x, int y) { return level[x] > level[y]; });
for (int l = 1, r; l <= n; l = r + 1) {
for (r = l; r < n && level[a[r + 1]] == level[a[l]]; ++r);
sort(a + l, a + r + 1, [](int x, int y) {
bool flag = 0;
if (x > y) flag = 1, swap(x, y);
return (tr.query(1, x - 1, p[x] + 1, p[y]) < tr.query(x + 1, y - 1, p[y] + 1, n)) ^ flag;
});
for (int i = l; i <= r; ++i) tr.insert(a[i], p[a[i]], i);
}
for (int i = 1; i <= n; ++i) b[a[i]] = i;
seg.build();
for (;;) {
auto res = seg.search();
for (int i: res) que.push(b[i]);
if (que.empty()) break;
int x = que.top(); que.pop(), seg.erase(a[x]);
int y = x;
if (!que.empty()) y = que.top(), que.pop(), seg.erase(a[y]);
ans.emplace_back(p[a[x]], p[a[y]]);
}
reverse(ans.begin(), ans.end());
printf("%d\n", ans.size());
for (auto i: ans) printf("%d %d\n", i.first, i.second);
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 3ms
memory: 3804kb
input:
8 4 3 8 2 1 7 6 5
output:
4 4 8 3 7 2 6 1 5
result:
ok da
Test #2:
score: 0
Accepted
time: 0ms
memory: 3564kb
input:
8 5 6 7 1 2 8 3 4
output:
4 7 8 5 6 1 2 3 4
result:
ok da
Test #3:
score: 0
Accepted
time: 2ms
memory: 3604kb
input:
4 1 2 4 3
output:
2 2 4 3 1
result:
ok da
Test #4:
score: 0
Accepted
time: 2ms
memory: 3616kb
input:
2 1 2
output:
1 1 2
result:
ok da
Test #5:
score: 0
Accepted
time: 2ms
memory: 3604kb
input:
2 2 1
output:
2 2 2 1 1
result:
ok da
Test #6:
score: 0
Accepted
time: 2ms
memory: 3816kb
input:
3 1 2 3
output:
2 3 3 1 2
result:
ok da
Test #7:
score: 0
Accepted
time: 2ms
memory: 3616kb
input:
3 1 3 2
output:
2 3 3 2 1
result:
ok da
Test #8:
score: 0
Accepted
time: 1ms
memory: 3620kb
input:
3 2 1 3
output:
2 2 2 1 3
result:
ok da
Test #9:
score: 0
Accepted
time: 2ms
memory: 3556kb
input:
3 2 3 1
output:
2 2 3 1 1
result:
ok da
Test #10:
score: 0
Accepted
time: 2ms
memory: 3620kb
input:
3 3 1 2
output:
2 3 3 1 2
result:
ok da
Test #11:
score: 0
Accepted
time: 2ms
memory: 3808kb
input:
3 3 2 1
output:
3 3 3 2 2 1 1
result:
ok da
Test #12:
score: 0
Accepted
time: 2ms
memory: 3804kb
input:
4 1 2 3 4
output:
2 3 4 1 2
result:
ok da
Test #13:
score: 0
Accepted
time: 0ms
memory: 3660kb
input:
4 1 2 4 3
output:
2 2 4 3 1
result:
ok da
Test #14:
score: 0
Accepted
time: 2ms
memory: 3620kb
input:
4 1 3 2 4
output:
2 4 3 2 1
result:
ok da
Test #15:
score: 0
Accepted
time: 2ms
memory: 3612kb
input:
4 1 3 4 2
output:
2 3 4 2 1
result:
ok da
Test #16:
score: -100
Wrong Answer
time: 2ms
memory: 3672kb
input:
4 1 4 2 3
output:
3 4 4 1 1 2 3
result:
wrong answer jury have better solution