/*
8
-6 -12
-2.5 -2.5
-1.333 0
-0.4 0.8
6 24
6 25
0 100
0 101
*/
//你的答案錯的
//错的原因在于你sort的时候应该是sort(stack,stack+top+1,com2)然而你写成了sort(stack,stack+top,com2)
8
-6 -12
-2.5 -2.5
-1.333 0
-0.4 0.8
6 24
6 25
0 100
0 101
*/
//你的答案錯的
//错的原因在于你sort的时候应该是sort(stack,stack+top+1,com2)然而你写成了sort(stack,stack+top,com2)
其他关键就是从反向思考当最后结束时那些线是什么样你就会发现其实那些线一定是一堆包络线不是上凸就是下凹这样用栈就阔以解决问题了就像优先队列的题目一样最开始我想的是李超线段树不过那样搞得话就大才小用了李超线段树是在线的而这个题目只要求离线所以呵呵。。。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
struct linee{
double k, b ;
int num;
}line[50001];
struct nodee{
linee c;
double x, y;
}stack[50001];
bool com1(linee a, linee b)
{
if (fabs(a.k-b.k)<1e-8)
{
if (a.b>b.b)
return true;
return false;
}
if (a.k < b.k)
{
return true;
}
if (a.k > b.k)
return false;
}
bool com2(nodee a, nodee b)
{
if (a.c.num == b.c.num)
return false;
if (a.c.num < b.c.num)
return true;
if (a.c.num>b.c.num)
return false;
}
double jiao(linee a, linee b)
{
double k = (b.b - a.b) / (a.k - b.k);
return k;
}
int top = -1;
int n;
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
double k, b;
scanf("%lf%lf", &k, &b);
//cout << k << " " << b << endl;
line[i].k = k;
line[i].b = b;
line[i].num = i;
}
sort(line, line + n, com1);
stack[++top].c = line[0];
for (int i = 1; i < n; i++)
{
if (fabs(stack[top].c.k - line[i].k)<1e-8)
{
continue;
}
if (top == 0)
{
stack[++top].c = line[i];
}
else
{
while (top>0&&jiao(line[i],stack[top].c)<=jiao(stack[top].c,stack[top-1].c))
{
top--;
}
stack[++top].c = line[i];
}
}
sort(stack, stack + top+1, com2);
for (int i = 0; i <= top; i++)
{
printf("%d ", stack[i].c.num + 1);
}
return 0;