Codeforces 536C Tavas and Pashmaks(凸壳)

题目链接 Tavas and Pashmaks

题目大意:n个人比赛,游泳和赛跑,游泳距离S,赛跑R。每个人对应两个速度(陆地和水上的),如果存在S,R,使得第i个人胜利,那么输出i

     题目要求输出所有的i

维护一个凸壳即可。

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)
#define fi		first
#define se		second

typedef long long LL;

const int N = 200010;

int x[N], y[N];
bool win[N];
set <pair <int, int> > s;
int my[N >> 4];
int sz;
pair <int, int> st[N];
int n, best;

void func(int xx, int yy){

	while (true){
		if (sz < 2) break;
		int x1 = st[sz - 2].fi, y1 = st[sz - 2].se;
		int x2 = st[sz - 1].fi, y2 = st[sz - 1].se;

		int x3 = xx, y3 = yy;
		if ((LL)x2 * (x1 - x3) * y3 * (y1 - y2) > (LL)x3 * (x1 - x2) * y2 * (y1 - y3))
			--sz;
		else break;
	}

	st[sz] = make_pair(xx, yy);
	++sz;
}	

int main(){

	scanf("%d", &n);
	rep(i, 1, n) scanf("%d%d", x + i, y + i);


	rep(i, 1, n) my[x[i]] = max(my[x[i]], y[i]);

	best = 0;
	dec(i, 10000, 1) if (my[i] > best){
		func(i, my[i]);
		best = my[i];
	}

	rep(i, 0, sz - 1) s.insert(st[i]);
	rep(i, 1, n)
		if ((int)s.count(make_pair(x[i], y[i])) > 0)
			win[i] = 1;

	rep(i, 1, n) if (win[i]) printf("%d\n", i);
	return 0;
}

 

posted @ 2017-07-16 23:39  cxhscst2  阅读(291)  评论(0编辑  收藏  举报