44// math, hash table, bitmasks
55class Solution {
66private:
7- template <typename A,typename B,typename C>
87struct TupleHash {
9- size_t operator ()(const tuple<A, B, C>& p)const {
10- size_t seed =0 ;
11- A a; B b; C c;
12- tie (a, b, c) = p;
13- seed ^= std::hash<A>{}(a) +0x9e3779b9 + (seed<<6 ) + (seed>>2 );
14- seed ^= std::hash<B>{}(b) +0x9e3779b9 + (seed<<6 ) + (seed>>2 );
15- seed ^= std::hash<C>{}(c) +0x9e3779b9 + (seed<<6 ) + (seed>>2 );
16- return seed;
17- }
18- };
19-
20- template <typename T>
21- struct PairHash {
22- size_t operator ()(const pair<T, T>& p)const {
23- size_t seed =0 ;
24- seed ^= std::hash<T>{}(p.first ) +0x9e3779b9 + (seed<<6 ) + (seed>>2 );
25- seed ^= std::hash<T>{}(p.second ) +0x9e3779b9 + (seed<<6 ) + (seed>>2 );
26- return seed;
8+ template <typename ... T>
9+ std::size_t operator ()(const std::tuple<T...>& t)const {
10+ return apply ([](const auto &... args) {
11+ std::size_t seed =0 ;
12+ ((seed ^= std::hash<std::decay_t <decltype (args)>>{}(args) +
13+ 0x9e3779b9 + (seed <<6 ) + (seed >>2 )), ...);
14+ return seed;
15+ }, t);
2716 }
2817 };
2918
@@ -32,7 +21,7 @@ class Solution {
3221auto ceil_divide = [](int a,int b) {
3322return (a + b -1 ) / b;
3423 };
35- unordered_map<tuple<int ,int ,int >, unordered_set<pair <int ,int >,PairHash< int >> , TupleHash< int , int , int > > lookup;
24+ unordered_map<tuple<int ,int ,int >, unordered_set<tuple <int ,int >,TupleHash> , TupleHash> lookup;
3625for (int i =0 ; i <size (points); ++i) {
3726const int x1 = points[i][0 ], y1 = points[i][1 ];
3827for (int j = i +1 ; j <size (points); ++j) {
@@ -44,6 +33,14 @@ class Solution {
4433int c = x1 * (y2 - y1) - y1 * (x2 - x1);
4534const int g =gcd (gcd (a, b), c);
4635 a /= g, b /= g, c /= g;
36+ for (const auto & x : {a, b, c}) {
37+ if (x) {
38+ if (x <0 ) {
39+ a = -a, b = -b, c = -c;
40+ }
41+ break ;
42+ }
43+ }
4744 lookup[{a, b, c}].emplace (x1, y1);
4845 lookup[{a, b, c}].emplace (x2, y2);
4946 }
@@ -58,7 +55,7 @@ class Solution {
5855int result = numeric_limits<int >::max ();
5956const int mask_upper_bound =1 <<size (lines);
6057for (int mask =0 ; mask < mask_upper_bound; ++mask) {
61- unordered_set<pair <int ,int >,PairHash< int > > covered;
58+ unordered_set<tuple <int ,int >,TupleHash > covered;
6259for (int i =0 , bit =1 ; bit <= mask; bit <<=1 , ++i) {
6360if (mask & bit) {
6461for (const auto & x : lookup[lines[i]]) {