#pragma GCC optimize ("O3") #pragma GCC target ("avx") #include using namespace std; struct Fraction { int64_t a, b; Fraction(int64_t a, int64_t b) : a(a), b(b) {} }; bool operator<(const Fraction &l, const Fraction &r) { return l.a * r.b < l.b * r.a; } Fraction operator+(const Fraction &l, const Fraction &r) { return Fraction(l.a * r.b + r.a * l.b, l.b * r.b); } Fraction operator-(const Fraction &l, const Fraction &r) { return Fraction(l.a * r.b - r.a * l.b, l.b * r.b); } bool operator==(const Fraction &l, const Fraction &r) { return l.a * r.b == r.a * l.b; } int main() { int n; cin >> n; vector> f(3); for (int i = 0; i < 3; i++) { f[i].emplace_back(1, 1); } for (int i = 0; i < n; i++) { int p, ta, tb; cin >> p >> ta >> tb; f[p].emplace_back(ta, ta + tb); } sort(f[2].begin(), f[2].end()); int64_t ans = 0; for (int i = 0; i < f[0].size(); i++) { for (int j = 0; j < f[1].size(); j++) { if (f[0][i] + f[1][j] < Fraction(1, 1)) { continue; } int k0 = lower_bound(f[2].begin(), f[2].end(), Fraction(1, 1) - f[0][i]) - f[2].begin(); int k1 = lower_bound(f[2].begin(), f[2].end(), Fraction(1, 1) - f[1][j]) - f[2].begin(); int k2 = lower_bound(f[2].begin(), f[2].end(), Fraction(2, 1) - f[0][i] - f[1][j]) - f[2].begin(); if (k2 < f[2].size() && f[0][i] + f[1][j] + f[2][k2] == Fraction(2, 1)) { ans--; } ans += f[2].size() - max(k0, k1); } } cout << ans << endl; }