BZOJ-3190 [JLOI2013]赛车

转成二元一次不等式组,然后半平面交。

#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cctype>
#include <algorithm>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define maxn 12345
using namespace std;
typedef long long ll;
inline int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x*f;
}
struct line{ll b, k; int n;} l[maxn];
bool cmp(line a, line b){return a.k>b.k || (a.k==b.k && a.b>b.b);}


int n, v[maxn], tot;
inline ll Get(line x, line y, line z){return (y.b-x.b)*(y.k-z.k)-(z.b-y.b)*(x.k-y.k);}
int main()
{
	n=read(); 
	rep(i, 1, n) l[i].b=read();
	rep(i, 1, n) l[i].k=read();
	rep(i, 1, n) l[i].n=i;
	sort(l+1, l+1+n, cmp);
	v[++tot]=1; rep(i, 2, n)
	{
		if (l[i].k==l[i-1].k && l[i].b==l[i-1].b) {v[++tot]=i; continue;}
		if (l[i].k==l[i-1].k) continue;
		while (tot>1)
			if (Get(l[i], l[v[tot]], l[v[tot-1]])<=0) break; else tot--;
		v[++tot]=i;
	}
	while (tot>1) 
		if (l[v[tot-1]].b-l[v[tot]].b<=0) break; else tot--;
	rep(i, 1, tot) v[i]=l[v[i]].n;
	sort(v+1, v+tot+1);
	printf("%d\n", tot); rep(i, 1, tot) printf("%d%c", v[i], i==tot?'\n':' ');
	return 0;
}
posted @ 2015-05-05 18:37  NanoApe  阅读(205)  评论(0编辑  收藏  举报
AmazingCounters.com