This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "teams.h"
#include <bits/stdc++.h>
 
using namespace std;
 
const int MAX_N = 500000;
const int NNODES = 15000000;
struct AintPersistent {
	AintPersistent *sl, *sr;
	int val;
	AintPersistent() {
		val = 0;
		sl = sr = NULL;
	}
} cache[NNODES];
int topcache;
vector<AintPersistent*> root;
AintPersistent* mynew() {
	return &cache[topcache++];
}
AintPersistent* init(int l = 1, int r = MAX_N) {
	AintPersistent *rez = mynew();
	if(l < r) {
		int mid = (l + r) / 2;
		rez->sl = init(l, mid);
		rez->sr = init(mid + 1, r);
	}
	return rez;
}
 
AintPersistent* updateDfs(int poz, int val, int l, int r, AintPersistent* T) {
	if(r < poz || poz < l) return T;
	if(l == r) {
		AintPersistent* rez = mynew();
		rez->val = T->val + val;
		return rez;
	} else if(l < r) {
		int mid = (l + r) / 2;
		AintPersistent* rez = mynew();
		rez->sl = updateDfs(poz, val, l, mid, T->sl);
		rez->sr = updateDfs(poz, val, mid + 1, r, T->sr);
		rez->val = rez->sl->val + rez->sr->val;
		return rez;
	}
	return T;
}
 
int queryDfs(int i, int j, int l, int r, AintPersistent* T) {
	if(j < l || r < i || j < i) return 0;
	if(i <= l && r <= j)
		return T->val;
	else {
		int mid = (l + r) / 2;
		return queryDfs(i, j, l, mid, T->sl) +
					 queryDfs(i, j, mid + 1, r, T->sr);
	}
}
 
void update(int timestamp, int poz, int val) {
	root.push_back(updateDfs(poz, val, 1, MAX_N, root[timestamp]));
}
 
int query(int timestamp, int i, int j) {
	return queryDfs(i, j, 1, MAX_N, root[timestamp]);
}
 
pair<int, int> points[MAX_N];
int atable[1+MAX_N], btable[1+MAX_N];
 
// de jos in sus
bool bsort(pair<int, int> a, pair<int, int> b) {
	return a.second < b.second;
}
 
// de la stanga la dreapta
bool asort(pair<int, int> a, pair<int, int> b) {
	return a.first < b.first;
}
int N;
 
int getRealA(int A) {
	int st = -1, dr = N;
	while(dr - st > 1) {
		int mid = (st + dr) / 2;
		if(atable[mid] <= A)
			st = mid;
		else
			dr = mid;
	}
	return st + 1;
}
 
int getRealB(int B) {
	int st = -1, dr = N;
	while(dr - st > 1) {
		int mid = (st + dr) / 2;
		if(btable[mid] <= B)
			st = mid;
		else
			dr = mid;
	}
	return st + 1;
}
int query(int a1, int b1, int a2, int b2) {
	return query(a2, b1, b2) - query(a1 - 1, b1, b2);
}
int binsrc(AintPersistent* plusTree, AintPersistent* minusTree, int val, int l, int r) {
	if(l == r) return l;
	int mid = (l + r) / 2;
	int lval = plusTree->sl->val - minusTree->sl->val;
	if(lval >= val)
		return binsrc(plusTree->sl, minusTree->sl, val, l, mid);
	else
		return binsrc(plusTree->sr, minusTree->sr, val - lval, mid + 1, r);
}
void init(int _N, int A[], int B[]) {
	N = _N;
	
	root.push_back(init());
	for(int i = 0; i < N; ++i)
		points[i] = make_pair(A[i], B[i]);
	
	sort(points, points + N, bsort);
	for(int i = 0; i < N; ++i) {
		btable[i] = points[i].second;
		points[i].second = i + 1;
	}
	
	sort(points, points + N, asort);
	for(int i = 0; i < N; ++i) {
		atable[i] = points[i].first;
		points[i].first = i + 1;
	}
	
	for(int i = 0; i < N; ++i)
		update(i, points[i].second, 1);
}
vector<pair<int, int> > corners;
int can(int M, int K[]) {
	sort(K, K + M);
	corners.clear();
	corners.push_back(make_pair(0, MAX_N));
	for(int i = 0; i < M; ++i) {
		int ak = getRealA(K[i]),
		    bk = getRealB(K[i] - 1);
		while(!corners.empty() && corners.back().second <= bk)
			corners.pop_back();
		while(!corners.empty() && K[i] > 0) {
			int x = query(corners.back().first + 1, bk + 1, ak, corners.back().second);
			if(x <= K[i]) {
				K[i] -= x;
				bk = corners.back().second;
				corners.pop_back();
			} else {
				int cut = query(corners.back().first + 1, 1, ak, bk);
				bk = binsrc(root[ak], root[corners.back().first], cut + K[i], 1, MAX_N);
				K[i] -= query(corners.back().first + 1, 1, ak, bk) - cut;
			}
		}
		corners.push_back(make_pair(ak, bk));
		if(K[i] > 0)
			return false;
	}
	return true;
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |