//凸包,Graham算法
//点编号0~n-1
//返回凸包结果Stack[0~Top-1]
Point List[maxn],Stack[maxn]; int Top;
bool cmp( Point a , Point b )
{
double tmp = (a-List[0])^(b-List[0]);
if ( tmp>0 ) return true;
else if ( tmp==0&&sgn( dist2( a , List[0] )-dist2( b , List[0] ) )<=0 ) return true;
else return false;
}
void Graham( int n )
{
int k = 0;
for ( int i=1 ; i<n ; i++ )
if ( List[i].y<List[k].y||(List[i].y==List[k].y&&List[i].x<List[k].x) ) k = i;
swap ( List[k] , List[0] );
sort ( List+1 , List+n , cmp );
if ( n==1 )
{
Top = 1;
Stack[0] = List[0];
return;
}
if ( n==2 )
{
Top = 2;
Stack[0] = List[0];
Stack[1] = List[1];
return;
}
Stack[0] = List[0];
Stack[1] = List[1];
Top = 2;
for ( int i=2 ; i<n ; i++ )
{
while ( Top>1&&((Stack[Top-1]-Stack[Top-2])^(List[i]-Stack[Top-2]))<=0 ) Top--;
Stack[Top++] = List[i];
}
}