Submission #257894

#TimeUsernameProblemLanguageResultExecution timeMemory
257894ChrisTRobots (IOI13_robots)C++17
76 / 100
1773 ms65536 KiB
#include <algorithm>
#include <vector>
#include <map>
#include "robots.h"
using namespace std;
using ll = long long;
using pii = pair<int,int>;
#define lc ind<<1
#define rc ind<<1|1
const int MN = 1e6 + 5, LOG = 18, MOD = 1e9 + 7;
struct Point {
	int x,y;
	bool operator< (const Point &o) const {
		return make_pair(x,y) < make_pair(o.x,o.y);
	}
};
bool cmp (const Point &a, const Point &b) {return make_pair(a.y,a.x) < make_pair(b.y,b.x);}
struct Segtree {
	pii tree[2097155];
	void build (int ind, int l, int r, vector<int> &v) {
		if (l == r) return (void) (tree[ind] = {v[l-1],l-1});
		int mid = (l + r) / 2;
		build(lc,l,mid,v); build(rc,mid+1,r,v);
		tree[ind] = max(tree[lc],tree[rc]);
	} 
	int findfirst (int ind, int l, int r) {
		if (l == r) return tree[ind].first > 0 ? l-1 : -1;
		int mid = (l + r) / 2;
		if (tree[lc].first > 0) return findfirst(lc,l,mid);
		return findfirst(rc,mid+1,r);   
	} 
	void update (int ind, int l, int r, int i, int v) {
		if (l == r) return (void) (tree[ind] = {v,l-1});
		int mid = (l + r) / 2;
		if (i <= mid) update(lc,l,mid,i,v);
		else update(rc,mid+1,r,i,v);
		tree[ind] = max(tree[lc],tree[rc]);
	}
	pii query (int ind, int tl, int tr, int l, int r) {
		if (tl > r || tr < l) return {-1,-1};
		if (l <= tl && tr <= r) return tree[ind];
		int mid = (tl + tr) / 2;
		return max(query(lc,tl,mid,l,r),query(rc,mid+1,tr,l,r));
	}
} xSeg, ySeg;
int putaway (int a, int b, int t, int *x, int *y, int *w, int *s) { //2 segtree + bsearch
	sort(x,x+a); sort(y,y+b); 
	vector<Point> xSrt(t), ySrt(t);
	for (int i = 0; i < t; i++) xSrt[i] = ySrt[i] = {w[i],s[i]};
	sort(xSrt.begin(),xSrt.end());
	sort(ySrt.begin(),ySrt.end(),cmp);
	vector<int> temp(t);
	for (int i = 0; i < t; i++) temp[i] = xSrt[i].y;
	xSeg.build(1,1,t,temp);
	for (int i = 0; i < t; i++) temp[i] = ySrt[i].x;
	ySeg.build(1,1,t,temp);
	map<Point,int> taken;
	auto del = [&] (Point &p) {
		//printf ("p {%d,%d}\n",p.x,p.y);
		int posX = lower_bound(xSrt.begin(),xSrt.end(),p) - xSrt.begin() + taken[p];
		int posY = lower_bound(ySrt.begin(),ySrt.end(),p,cmp) - ySrt.begin() + taken[p];
		taken[p]++; 
		//printf ("posX %d posY %d\n",posX,posY);
		xSeg.update(1,1,t,posX+1,-1e9); ySeg.update(1,1,t,posY+1,-1e9);
	};
	int ret = 0, done = 0;
	while (done < t) {
		++ret; bool add = 0; 
		int lstLine = -1;
		while (1) {
			int go = xSeg.findfirst(1,1,t);
			//printf ("go %d\n",go);
			if (go == -1) break;
			int nxtLine = max(lstLine + 1,(int)(upper_bound(x,x+a,xSrt[go].x)-x));
			//printf ("nxtLine %d\n",nxtLine);
			if (nxtLine >= a) break;
			int ed = lower_bound(xSrt.begin(),xSrt.end(),Point{x[nxtLine],0})-xSrt.begin();
			//printf ("ed %d\n",ed);
			int take = xSeg.query(1,1,t,1,ed).second;
			//printf ("take %d\n",take);
			del(xSrt[take]); add = 1; ++done; lstLine = nxtLine;
		}
		lstLine = -1;
		while (1) {
			int go = ySeg.findfirst(1,1,t);
			//printf ("y go %d\n",go);
			if (go == -1) break;
			int nxtLine = max(lstLine + 1,(int)(upper_bound(y,y+b,ySrt[go].y)-y));
			//printf ("y nxtLine %d\n",nxtLine);
			if (nxtLine >= b) break;
			int ed = lower_bound(ySrt.begin(),ySrt.end(),Point{0,y[nxtLine]},cmp)-ySrt.begin();
			//printf ("y ed %d\n",ed);
			int take = ySeg.query(1,1,t,1,ed).second;
			//printf ("y take %d\n",take);
			del(ySrt[take]); add = 1; ++done; lstLine = nxtLine;
		}
		if (!add) return -1;
	}
	return ret;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...