题目链接 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 ", i); return 0; }