对于每一个点,它与原点的连线将平面划分为两个半平面,我们统计连线的逆时针方向的半平面中的点的个数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.