제출 #793479

#제출 시각아이디문제언어결과실행 시간메모리
793479Username4132Teams (IOI15_teams)C++14
100 / 100
1632 ms387568 KiB
#include "teams.h"
#include<iostream>
#include<vector>
#include<algorithm>
#include<cassert>
using namespace std;
using pii = pair<int, int>;
#define forn(i, n) for(int i=0; i<(int)n; ++i)
#define forsn(i, s, n) for(int i=s; i<(int)n; ++i)
#define PB push_back
#define F first
#define S second

struct Vertex{
	int value;
	Vertex *l, *r;
	Vertex(int _value) : value(_value), l(NULL), r(NULL) {}
	Vertex(Vertex* _l, Vertex* _r) : value(_l->value + _r->value), l(_l), r(_r) {}
};

Vertex* build(int tl, int tr){
	if(tl==tr) return new Vertex(0);
	int tm = (tl+tr)>>1;
	return new Vertex(build(tl, tm), build(tm+1, tr));
}

Vertex* update(Vertex* v, int tl, int tr, int pos, int delta){
	if(tl==tr) return new Vertex(v->value + delta);
	int tm = (tl+tr)>>1;
	if(pos<=tm) return new Vertex(update(v->l, tl, tm, pos, delta), v->r);
	else return new Vertex(v->l, update(v->r, tm+1, tr, pos, delta));
}

int query(Vertex* v, int l, int r, int tl, int tr){
	if(l>r) return 0;
	if(l==tl && r==tr) return v->value;
	int tm = (tl+tr)>>1;
	return query(v->l, l, min(r, tm), tl, tm) + query(v->r, max(l, tm+1), r, tm+1, tr);
}

pii srch(Vertex* vl, Vertex* vr, int tl, int tr, int target){
	assert(target>0);
	if(tl==tr) return {tl, target};
	int tm = (tl+tr)>>1;
	int sum = vr->l->value - vl->l->value;
	if(sum < target) return srch(vl->r, vr->r, tm+1, tr, target-sum);
	else return srch(vl->l, vr->l, tl, tm, target);
}

const int MAXN = 500010;
int n;
Vertex* roots[MAXN];
vector<int> vals[MAXN];

void init(int N, int A[], int B[]) {
	n=N;
	roots[0]=build(0, n+4);
	forn(i, n) vals[A[i]].PB(B[i]);
	forsn(i, 1, n+1){
		roots[i]=roots[i-1];
		for(int el:vals[i]) roots[i]=update(roots[i], 0, n+4, el, 1);
	}
}

int cou(int x1, int x2, int y1, int y2){
	return query(roots[max(x2-1, 0)], y1, y2-1, 0, n+4) - query(roots[max(x1-1, 0)], y1, y2-1, 0, n+4);
}

pii binary(int x1, int x2, int bound){
	return srch(roots[max(x1-1, 0)], roots[max(x2-1, 0)], 0, n+4, bound);
}

bool solve(vector<pii>& dom, vector<int>& xt, pii ins, int target){
	int del=0;
	while(ins.S >= dom.back().S){
		if(ins.S == dom.back().S) del=xt.back();
		dom.pop_back();
		xt.pop_back();
	}
	while(true){
		int obt = cou(dom.back().F + 1, ins.F + 1, ins.S, dom.back().S) - del;
		if(obt < target){
			target-=obt;
			ins.S=dom.back().S;
			del=xt.back();
			dom.pop_back();
			xt.pop_back();
		}
		else{
			int base = cou(dom.back().F + 1, ins.F + 1, 0, ins.S) + del;
			pii res = binary(dom.back().F + 1, ins.F + 1, target + base);
			dom.PB({ins.F, res.F});
			xt.PB(res.S);
			return true;
		}
		if(dom.empty()) return false;
	}
}

int can(int m, int arr[]) {
	int dummy=0;
	forn(i, m){
		dummy+=arr[i];
		if(dummy>n) return 0;
	}
	sort(arr, arr+m);
	vector<pii> dom;
	vector<int> xt;
	dom.PB({-1, n+2});
	xt.PB(0);
	int cnt=0;
	forn(i, m){
		++cnt;
		if(i==m-1 || arr[i]!=arr[i+1]){
			if(!solve(dom, xt, {arr[i], arr[i]}, cnt*arr[i])){
				return 0;
			}
			cnt=0;
		}
	}
	return 1;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...