#include using namespace std; using LL = long long; using point = pair; const LL prime = 1000000007LL; LL det_mod(point a, point b, LL m) { return (((((a.first * b.second) % m) - ((a.second * b.first) % m)) % m) + m) % m; } LL pow_mod(LL a, LL b, LL m) { if(b == 0) return 1; LL sq = pow_mod(a, b/2, m); return (((b % 2 == 1) ? a : 1) * ((sq * sq) % m)) % m; } LL rev_mod(LL a, LL m) { return pow_mod(a, m-2, m); } point center_of_mass_mod(vector &tab, LL m) { int N = tab.size(); LL X = 0, Y = 0, A = 0; for(int i = 0; i < tab.size(); ++i) { LL aux = det_mod(tab[i], tab[(i+1) % N], m); X = (((((tab[i].first + tab[(i+1) % N].first) * aux) + X) % m) + m) % m; Y = (((((tab[i].second + tab[(i+1) % N].second) * aux) + Y) % m) + m) % m; A = (A + aux) % m; } LL coef = rev_mod((3 * A) % m, m); return make_pair((X * coef) % m, (Y * coef) % m); } pair center_of_mass(vector &tab) { int N = tab.size(); double X = 0, Y = 0, A = 0; for(int i = 0; i < tab.size(); ++i) { pair a = tab[i], b = tab[(i + 1) % N]; double aux = (a.first * b.second) - (a.second * b.first); X += (a.first + b.first) * aux; Y += (a.second + b.second) * aux; A += aux; } return make_pair(X / (3 * A), Y / (3 * A)); } point point_minus(point A, point B) { return make_pair(A.first - B.first, A.second - B.second); } bool aligned(point A, point B, point C, LL m) { return det_mod(point_minus(A, B), point_minus(C, B), m) == 0; } vector count_next_not_P(vector &ttab, const pair& bary, const point& bary_mod, bool (*P)(const point&, const point&, const pair&, const point&)) { int N = ttab.size(); vector tab = ttab; for(point x : ttab) tab.push_back(x); vector ans(N,-1); int cpt = 1; for(int i = 0; i < N; ++i) { cpt = max(cpt, i+1); while(P(tab[i], tab[cpt], bary, bary_mod)) cpt++; ans[i] = cpt; } return ans; } double angle(const pair& aa, const pair& bb, const pair& bary) { pair a = make_pair(aa.first - bary.first, aa.second - bary.second); pair b = make_pair(bb.first - bary.first, bb.second - bary.second); double dot = (a.first * b.first) + (a.second * b.second); double det = (a.first * b.second) - (a.second * b.first); return atan2(det, dot); } double angle(const pair& p, const pair& bary) { return angle(p, {1, 0}, bary); } bool opposite_side(const point &A, const point &B, const pair& bary, const point& bary_mod) { return aligned(A,B,bary_mod, prime) && fabs(angle(A, B, bary)) > 1; } bool same_side(const point &A, const point &B, pair bary, const point &bary_mod) { return aligned(A, B, bary_mod, prime) && !opposite_side(A, B, bary, bary_mod); } bool is_CW(const point &A, const point &B, const pair &bary) { double ang = angle(A, B, bary); return angle(A, B, bary) > 0; } int main() { long long N; cin >> N; vector tab; for(int i = 0; i < N; ++i) { long long x, y; cin >> x >> y; tab.push_back(make_pair(x,y)); } pair bary = center_of_mass(tab); point bary_mod = center_of_mass_mod(tab, prime); vector ttab; for(auto p : tab) if(((p.first + prime) % prime != bary_mod.first) || ((p.second + prime) % prime != bary_mod.second)) { ttab.push_back(p); } tab = ttab; N = tab.size(); sort(tab.begin(), tab.end(), [bary] (const auto& lhs, const auto& rhs) { return angle(lhs, bary) > angle(rhs, bary); }); auto fst_opposite = count_next_not_P(tab, bary, bary_mod, [](const point& lhs, const point& rhs, const pair& bary_, const point& bary_mod_) { return (!opposite_side(lhs, rhs, bary_, bary_mod_)) && (same_side(lhs,rhs,bary_,bary_mod_) || is_CW(lhs,rhs,bary_)); } ); auto fst_left = count_next_not_P(tab, bary, bary_mod, [](const point& lhs, const point& rhs, const pair& bary_, const point& bary_mod_) { return same_side(lhs, rhs, bary_, bary_mod_) || is_CW(lhs, rhs, bary_) || opposite_side(lhs, rhs, bary_, bary_mod_); } ); LL ans = 0; for(int i = 0; i < N; ++i) { LL opposite = fst_left[i] - fst_opposite[i]; LL after = N + i - fst_left[i]; ans += (after + opposite) * (after + opposite - 1) / 2LL; ans -= (opposite - 1) * opposite / 2; } cout << N * (N-1) * (N-2) / 6 - ans << endl; }