Description
给出一堆点,问有多少包含原点的三角形,\(n\leqslant 10^5\).
Sol
极角排序.
首先按极角大小排一下序,我先按象限排再计算一下叉积也相当于极角排序了...其实主要是我不太会用cmath里的atan什么的...
然后每次维护一个半平面,他和这些半平面中的点形成的三角形都不合法.
Code
/**************************************************************
Problem: 1914
User: BeiYu
Language: C++
Result: Accepted
Time:392 ms
Memory:2868 kb
****************************************************************/
#include <bits/stdc++.h>
using namespace std;
#define debug(a) cout<<#a<<"="<<a<<" "
#define mpr make_pair
#define x first
#define y second
typedef long long LL;
typedef pair< LL,LL > pr;
const int N = 1e5+50;
int n;LL ans;
pr p[N];
inline int in(int x=0,char ch=getchar(),int v=1) {
while(ch>'9' || ch<'0') v=(ch=='-'?-1:v),ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x*v;
}
double Len(const pr &a) { return sqrt(a.x*a.x+a.y*a.y); }
LL operator * (const pr &a,const pr &b) { return a.x*b.y-a.y*b.x; }
int cmp(const pr &a,const pr &b) {
// return atan2(a.y,a.x) < atan2(b.y,b.x);
if((b.y>=0) != (a.y>=0)) return a.y>b.y;
double l1=Len(a),l2=Len(b);
if(a.y<0) {
return (a.x*l2 == b.x*l1)? (l1<l2) : a.x*l2<b.x*l1;
} else {
return (a.x*l2 == b.x*l1)? (l1<l2) : a.x*l2>b.x*l1;
}
}
int main() {
n=in();
for(int i=0;i<n;i++) {
int x=in(),y=in();
// debug(x),debug(y)<<endl;
p[i]=mpr(x,y);
}
sort(p,p+n,cmp);
// for(int i=0;i<n;i++) cout<<p[i].x<<" "<<p[i].y<<endl;
ans=(LL)n*(n-1)*(n-2)/6;
for(int i=0,s=1,l=1;i<n;i++) {
while(l!=i && (p[i]*p[l]>=0)) s++,l=(l+1)%n;
// debug(l),debug(s)<<endl;
ans-=(LL)(s-1)*(s-2)/2;
s--;
}
printf("%lld\n",ans);
return 0;
}