对于每一个点,它与原点的连线将平面划分为两个半平面,我们统计连线的逆时针方向的半平面中的点的个数N,
这N个点与这个点构成的N(N-1)/2个三角形都是不包含原点的.最后只要用总个数减去这些三角形的和就是答案.
统计过程极角排序后可以做到O(N).
/**************************************************************
Problem: 1914
User: exponent
Language: Pascal
Result: Accepted
Time:260 ms
Memory:1008 kb
****************************************************************/
type point=record
x,y:longint;
end;
const maxn=100001;
var p:array[0..maxn] of point;
ans,tmp,count:int64;
n,i,j:longint;
function cross(a,b:point):int64;
begin
exit(int64(a.x)*int64(b.y)-int64(b.x)*int64(a.y));
end;
function cmp(a,b:point):boolean; //return angle(a)<angle(b)
begin
if (a.y>0)and(b.y<=0) then exit(true);
if (b.y>0)and(a.y<=0) then exit(false);
if cross(a,b)>0 then exit(true);
exit(false);
end;
procedure sort(l,r:longint);
var i,j:longint;
mid,temp:point;
begin
i:=l; j:=r;
mid:=p[(l+r)>>1];
while i<=j do
begin
while cmp(p[i],mid) do inc(i);
while cmp(mid,p[j]) do dec(j);
if i<=j then
begin
temp:=p[i];
p[i]:=p[j];
p[j]:=temp;
inc(i); dec(j);
end;
end;
if i<r then sort(i,r);
if j>l then sort(l,j);
end;
begin
readln(n);
for i:=1 to n do readln(p[i].x,p[i].y);
sort(1,n);
j:=1;
count:=0;
for i:=1 to n do
begin
while cross(p[i],p[j mod n+1])>=0 do
begin
if j mod n+1=i then break;
j:=j mod n+1;
inc(count);
end;
inc(tmp,count*(count-1)>>1);
dec(count);
end;
ans:=int64(n)*int64(n-1) div 2*int64(n-2) div 3;
writeln(ans-tmp);
end.
浙公网安备 33010602011771号