QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#61320 | #2555. Two Bullets | alpha1022 | WA | 2ms | 3664kb | C++14 | 5.0kb | 2022-11-12 09:53:11 | 2022-11-12 09:53:14 |
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 * 700 + 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); }
int prev(int x, int u, int tl, int tr) {
if (seg[u].min >= p[x]) return 0;
if (tl == tr) return tl;
int mid = (tl + tr) >> 1;
if (x <= mid) return prev(x, ls, tl, mid);
int ret = prev(x, rs, mid + 1, tr);
if (!ret) ret = prev(x, ls, tl, mid);
return ret;
}
int prev(int x) { return prev(x, 1, 1, n); }
void undo(int l, int r, int u, int tl, int tr) {
seg[u].vis = 0;
if (l <= tl && tr <= r) return ;
int mid = (tl + tr) >> 1;
if (l <= mid) undo(l, r, ls, tl, mid);
if (r > mid) undo(l, r, rs, mid + 1, tr);
}
void undo(int l, int r) { undo(l, r, 1, 1, n); }
void erase(int x, int u, int tl, int tr) {
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) {
int y = prev(x, 1, 1, n);
undo(y + 1, x, 1, 1, n), erase(x, 1, 1, n);
}
void search(vector<int> &ret, bool flag, int rmin, int u, int tl, int tr) {
if (seg[u].min >= rmin || seg[u].vis) return ;
flag &= seg[u].vis, seg[u].vis = 1;
if (tl == tr) { ret.push_back(tl); return ; }
int mid = (tl + tr) >> 1;
search(ret, flag, rmin, rs, mid + 1, tr);
search(ret, flag, min(rmin, seg[rs].min), ls, tl, mid);
}
vector<int> search() {
vector<int> ret;
search(ret, 1, 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);
}
详细
Test #1:
score: 0
Wrong Answer
time: 2ms
memory: 3664kb
input:
8 4 3 8 2 1 7 6 5
output:
4 4 4 3 3 2 2 1 5
result:
FAIL removed all buildings