QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#425025 | #964. Excluded Min | KinNa | WA | 6ms | 15428kb | C++14 | 4.9kb | 2024-05-29 21:25:37 | 2024-05-29 21:25:38 |
Judging History
answer
#include <algorithm>
#include <iostream>
#include <vector>
#include <set>
using namespace std;
const int N = 5e5 + 10;
int n, m, a[N];
struct Bit {
int bt[N];
void upd(int x, int v) {while (x <= n) {bt[x] += v; x += x & -x;}}
int qry(int x) {int res = 0; while (x) {res += bt[x]; x -= x & -x;} return res;}
int qry(int l, int r) {return qry(r) - qry(l - 1);}
} bit;
struct Query {int l, r, id;} q[N];
struct Node {int mx, tag, ls, rs;} t[N << 4]; int tot;
struct Seg {
#define mid (l + r >> 1)
#define lrt (t[rt].ls)
#define rrt (t[rt].rs)
#define MAXN m + 1
int Rt;
void pushr(int rt, int v) {t[rt].mx += v; t[rt].tag += v;}
void pushdown(int rt) {
if (t[rt].tag) {
if (lrt) pushr(lrt, t[rt].tag);
if (rrt) pushr(rrt, t[rt].tag);
t[rt].tag = 0;
}
}
void build(int *a, int l, int r, int &rt) {
if (!rt) rt = ++tot;
if (l == r) {t[rt].mx = a[l]; return ;}
build(a, l, mid, lrt); build(a, mid + 1, r, rrt);
t[rt].mx = max(t[lrt].mx, t[rrt].mx);
}
void build(int *a) {build(a, 1, MAXN, Rt);}
void upd(int ll, int rr, int v, int l, int r, int rt) {
if (ll > rr) return ;
if (ll <= l && r <= rr) {pushr(rt, v); return ;}
pushdown(rt);
if (ll <= mid) upd(ll, rr, v, l, mid, lrt);
if (mid < rr) upd(ll, rr, v, mid + 1, r, rrt);
t[rt].mx = max(t[lrt].mx, t[rrt].mx);
}
void upd(int ll, int rr, int v) {upd(ll, rr, v, 1, MAXN, Rt);}
void chg(int p, int v, int l, int r, int rt) {
if (l == r) {t[rt].mx = v; return ;}
pushdown(rt);
if (p <= mid) chg(p, v, l, mid, lrt);
else chg(p, v, mid + 1, r, rrt);
t[rt].mx = max(t[lrt].mx, t[rrt].mx);
}
void chg(int p, int v) {chg(p, v, 1, MAXN, Rt);}
int qry(int ll, int rr, int l, int r, int rt) {
if (ll > rr) return 0;
if (ll <= l && r <= rr) return t[rt].mx;
pushdown(rt);
if (rr <= mid) return qry(ll, rr, l, mid, lrt);
if (mid < ll) return qry(ll, rr, mid + 1, r, rrt);
return max(qry(ll, rr, l, mid, lrt), qry(ll, rr, mid + 1, r, rrt));
}
int qry(int ll = 1, int rr = MAXN) {return qry(ll, rr, 1, MAXN, Rt);}
int find(int k, int l, int r, int rt) {
if (l == r) {return l;}
pushdown(rt);
if (t[lrt].mx > k) return find(k, l, mid, lrt);
else return find(k, mid + 1, r, rrt);
}
int find(int k) {return find(k, 1, MAXN, Rt);}
int del(int l, int r, int rt) {
if (l == r) {t[rt].mx = -1e9; return l;}
pushdown(rt); int res;
if (t[lrt].mx == t[rt].mx) res = del(l, mid, lrt);
else if (t[rrt].mx == t[rt].mx) res = del(mid + 1, r, rrt);
else res = -1;
t[rt].mx = max(t[lrt].mx, t[rrt].mx);
return res;
}
int del() {return del(1, MAXN, Rt);}
} mx, seg;
int pmx[N], r[N], v[N], ans[N];
vector <int> pos[N];
int Maxval;
vector <int> live;
bool cmp(int A, int B) {return q[A].l ^ q[B].l ? q[A].l < q[B].l : q[A].r < q[B].r;}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
Maxval = max(Maxval, a[i]);
pos[a[i]].push_back(i);
bit.upd(i, 1);
}
for (int i = 1; i <= m; ++i)
cin >> q[i].l >> q[i].r, q[i].id = i;
sort(q + 1, q + m + 1, [](Query A, Query B) {return A.l ^ B.l ? A.l < B.l : A.r > B.r;});
for (int i = 1; i <= m; ++i) {
r[i] = q[i].r;
pmx[i] = max(pmx[i - 1], q[i].r);
if (q[i].r > pmx[i - 1]) live.push_back(i);
v[i] = q[i].r > pmx[i - 1] ? q[i].r - q[i].l + 1 : -1e9;
}
r[m + 1] = -1e9; mx.build(r); v[m + 1] = -1e9; seg.build(v);
for (int i = Maxval * 2; i >= 0; --i) {
// cout << " " << i << endl;
// if (pos[i].empty()) continue;
for (int p : pos[i]) {
bit.upd(p, -1); q[m + 1] = {p, 0};
int l = lower_bound(live.begin(), live.end(), m + 1, [](int A, int B) {return q[A].r < q[B].r;}) - live.begin();
q[m + 1].r = n + 1;
int r = lower_bound(live.begin(), live.end(), m + 1, cmp) - live.begin() - 1;
while (0 <= l && l < live.size() && q[live[l]].r < p && l <= r) ++l;
while (0 <= r && r < live.size() && q[live[r]].l > p && l <= r) --r;
if (l > r) continue;
l = live[l]; if (r >= 0) r = live[r];
seg.upd(l, r, -1);
}
while (seg.qry() >= i) {
int x = seg.del();
ans[q[x].id] = i;
mx.chg(x, -1e9);
vector <int>::iterator it = lower_bound(live.begin(), live.end(), x, cmp);
int lst, nxt, val;
if (it - live.begin() > 0) lst = live[it - live.begin() - 1];
else lst = 0;
if (it - live.begin() == live.size() - 1) nxt = n + 1;
else nxt = live[it - live.begin() + 1];
live.erase(it);
while (mx.find(r[lst]) != m + 1 && (live.empty() || lower_bound(live.begin(), live.end(), mx.find(r[lst]), cmp) == live.end() || *lower_bound(live.begin(), live.end(), mx.find(r[lst]), cmp) != nxt)) {
val = mx.find(r[lst]);
// if (lst == val) break;
live.insert(lower_bound(live.begin(), live.end(), val, cmp), val);
seg.chg(val, bit.qry(q[val].l, q[val].r));
lst = val;
}
}
}
for (int i = 1; i <= m; ++i)
cout << ans[i] << endl;
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 15428kb
input:
3 3 0 0 2 1 3 2 3 3 3
output:
3 1 0
result:
ok 3 number(s): "3 1 0"
Test #2:
score: 0
Accepted
time: 6ms
memory: 15416kb
input:
3 2 1 2 2 1 2 1 3
output:
0 3
result:
ok 2 number(s): "0 3"
Test #3:
score: 0
Accepted
time: 0ms
memory: 15420kb
input:
10 10 3 0 3 3 9 7 9 6 0 7 3 3 9 9 4 6 1 9 3 4 2 4 7 10 3 7 5 7 2 7
output:
0 1 0 5 0 1 1 0 0 1
result:
ok 10 numbers
Test #4:
score: -100
Wrong Answer
time: 6ms
memory: 15396kb
input:
10 10 3 0 0 0 5 1 1 1 2 1 1 2 8 8 5 7 1 7 2 2 1 5 5 6 4 6 3 10 6 8
output:
0 0 2 7 0 3 0 2 8 3
result:
wrong answer 1st numbers differ - expected: '1', found: '0'