记录编号 196251 评测结果 AAAAAAAAAAAA
题目名称 [USACO Jan07]考试 最终得分 100
用户昵称 Gravatarluoyuchu 是否通过 通过
代码语言 C++ 运行时间 0.037 s
提交时间 2015-10-21 11:18:14 内存使用 2.22 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <ctime>
#include <map>
#include <set>

#define dig(...) fprintf(stderr, __VA_ARGS__)

using namespace std;

template <class TAT>
void read(TAT &a)
{
	static char cc;
	static bool fff;
	while (((cc = getchar()) < '0' || cc > '9') && cc != '-');
	if (cc == '-') fff = 1, a = 0;
	else fff = 0, a = cc - 48;
	while ((cc = getchar()) >= '0' && cc <= '9') a = a * 10 + cc - 48;
	if (fff) a = -a;
}
template <class TAT>
void write(TAT a)
{
	static char cc[25];
	static int ct;
	if (a == 0) {putchar('0'); return;}
	if (a < 0) {putchar('-'); a = -a;}
	ct = 0;
	while (a) {cc[++ct] = a % 10 + 48; a /= 10;}
	while (ct) {putchar(cc[ct--]);}
}
void begin()
{
	freopen("schul.in", "r", stdin);
	freopen("schul.out", "w", stdout);
}
void end()
{
	fclose(stdin);
	fclose(stdout);
}
template <class TAT>
void Ckmin(TAT &a, const TAT &b)
{
	if (a > b) a = b;
}
template <class TAT>
void Ckmax(TAT &a, const TAT &b)
{
	if (a < b) a = b;
}

const int maxn = 50005;

int n;
struct Point
{
	int x, y;
	Point() {}
	Point(int xx, int yy):x(xx), y(yy) {}
	Point operator - (const Point &b) const
	{
		return Point(x - b.x, y - b.y);
	}
}dot[maxn];
int cross(const Point &a, const Point &b)
{
	return (a.x * b.y - a.y * b.x);
}
bool cmp_Bigger(const Point &a, const Point &b)
{
	return (a.y * b.x < b.y * a.x);
}
bool cmp_Less(const Point &a, const Point &b)
{
	return (a.y * b.x > b.y * a.x);
}
double xie[maxn] = {0};
double worst[maxn] = {0};
double best[maxn] = {0};
Point stack[maxn];
int st = 0;

void Init()
{
	register int i, j, k;
	read(n);
	for (i = 1; i <= n; ++i)
	{
		read(dot[i].y);
		read(dot[i].x);
	}
}

void PrepareWorst()
{
	register int i, j, k;
	register int Sx = 0, Sy = 0;
	sort(dot + 1, dot + 1 + n, cmp_Less);
	for (i = 1; i <= n; ++i)
	{
		Sx += dot[i].x;
		Sy += dot[i].y;
		xie[i] = Sy / (double)Sx;
	}
	st = 0;
	for (i = 1; i <= n; ++i)
	{
		while (st >= 1 && stack[st].x <= dot[i].x) --st;
		while (st >= 2 && cross(stack[st] - stack[st - 1], dot[i] - stack[st]) >= 0) --st;
		stack[++st] = dot[i];
		while (st >= 2 && (stack[st].y - stack[st - 1].y) > xie[i] * (stack[st].x - stack[st - 1].x)) --st;
		worst[i] = stack[st].y - stack[st].x * xie[i];
	}
	reverse(xie + 1, xie + n);
	reverse(worst + 1, worst + n);
}

void PrepareBest()
{
	register int i, j, k;
	sort(dot + 1, dot + 1 + n, cmp_Bigger);
	st = 0;
	for (i = 1; i <= n; ++i)
	{
		while (st >= 1 && stack[st].x >= dot[i].x) --st;
		while (st >= 2 && cross(stack[st] - stack[st - 1], dot[i] - stack[st]) >= 0) --st;
		stack[++st] = dot[i];
		while (st >= 2 && (stack[st].y - stack[st - 1].y) < xie[i] * (stack[st].x - stack[st - 1].x)) --st;
		best[i] = stack[st].y - stack[st].x * xie[i];
	}
}

void Solve()
{
	register int i, j, k;
	register int cnt = 0;
	for (i = 1; i < n; ++i)
	{
		if (best[i] > worst[i])
		{
			++cnt;
		}
	}
	write(cnt); putchar('\n');
	for (i = 1; i < n; ++i)
	{
		if (best[i] > worst[i])
		{
			write(i);
			putchar('\n');
		}
	}
}

int main()
{
	begin();
	Init();
	PrepareWorst();
	PrepareBest();
	Solve();
	end();
	return 0;
}