QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#425005#964. Excluded MinKinNaWA 0ms15432kbC++144.7kb2024-05-29 21:03:362024-05-29 21:03:36

Judging History

This is the latest submission verdict.

  • [2024-05-29 21:03:36]
  • Judged
  • Verdict: WA
  • Time: 0ms
  • Memory: 15432kb
  • [2024-05-29 21:03:36]
  • Submitted

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] ? n : -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;
			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;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 15416kb

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: 0ms
memory: 15428kb

input:

3 2
1 2 2
1 2
1 3

output:

0
3

result:

ok 2 number(s): "0 3"

Test #3:

score: -100
Wrong Answer
time: 0ms
memory: 15432kb

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
0
0
10
0
0
10
0
0
0

result:

wrong answer 2nd numbers differ - expected: '1', found: '0'