// includes {{{ #include #include #include #include #include #include #include #include #include #include #include #include #include #include // #include // #include // #include // #include // }}} using namespace std; using ll = long long; // #undef DEBUG // #define DEBUG // DEBUG {{{ #include #include #include #include #include #include #include #include #include template < int n, class... T > typename std::enable_if< (n >= sizeof...(T)) >::type __output_tuple( std::ostream &, std::tuple< T... > const &) {} template < int n, class... T > typename std::enable_if< (n < sizeof...(T)) >::type __output_tuple( std::ostream &os, std::tuple< T... > const &t) { os << (n == 0 ? "" : ", ") << std::get< n >(t); __output_tuple< n + 1 >(os, t); } template < class... T > std::ostream &operator<<(std::ostream &os, std::tuple< T... > const &t) { os << "("; __output_tuple< 0 >(os, t); os << ")"; return os; } template < class T, class U > std::ostream &operator<<(std::ostream &os, std::pair< T, U > const &p) { os << "(" << p.first << ", " << p.second << ")"; return os; } template < class T > std::ostream &operator<<(std::ostream &os, const std::stack< T > &a) { os << "{"; for(auto tmp = a; tmp.size(); tmp.pop()) os << (a.size() == tmp.size() ? "" : ", ") << tmp.top(); os << "}"; return os; } template < class T, class Container, class Compare > std::ostream &operator<<(std::ostream &os, std::priority_queue< T, Container, Compare > a) { os << "{ (top) "; while(a.size()) os << a.top() << (a.size() == 1 ? "" : ", "), a.pop(); os << " }"; return os; } template < class T, class Container > std::ostream &operator<<(std::ostream &os, std::queue< T, Container > a) { os << "{ "; while(a.size()) os << a.front() << (a.size() == 1 ? "" : ", "), a.pop(); os << " }"; return os; } #ifdef DEBUG #if !defined(DEBUG_OUT) #define DEBUG_OUT std::cerr #endif #define dump(...) \ [&]() { \ auto __debug_tap = std::make_tuple(__VA_ARGS__); \ DEBUG_OUT << "[" << __LINE__ << "] " << #__VA_ARGS__ << " = " << __debug_tap \ << std::endl; \ }() template < class T > inline void dump2D(T &d, size_t sizey, size_t sizex) { for(size_t i = 0; i < sizey; i++) { DEBUG_OUT << "\t"; for(size_t j = 0; j < sizex; j++) DEBUG_OUT << d[i][j] << (j + 1 == sizex ? "" : "\t"); DEBUG_OUT << std::endl; } } template < class T > inline void dump1D(T &d, size_t sizey) { for(size_t i = 0; i < sizey; i++) { DEBUG_OUT << d[i] << (i + 1 == sizey ? "" : " "); } DEBUG_OUT << std::endl; } template < class T, class = typename std::iterator_traits< decltype(begin(T())) >::value_type, class = typename std::enable_if< !std::is_same< T, std::string >::value >::type > std::ostream &operator<<(std::ostream &os, const T &a) { os << "{"; for(auto ite = begin(a); ite != end(a); ++ite) os << (ite == begin(a) ? "" : ", ") << *ite; os << "}"; return os; } #else #define dump(...) ((void) 42) #define dump2D(...) ((void) 42) #define dump1D(...) ((void) 42) template < class T, class = typename std::iterator_traits< decltype(begin(T())) >::value_type, class = typename std::enable_if< !std::is_same< T, std::string >::value >::type > std::ostream &operator<<(std::ostream &os, const T &a) { for(auto ite = begin(a); ite != end(a); ++ite) os << (ite == begin(a) ? "" : " ") << *ite; return os; } #endif // }}} /// --- math {{{ /// ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); } ll lcm(ll a, ll b) { return a / gcd(a, b) * b; } ll extgcd(ll a, ll b, ll &x, ll &y) { ll d; return b == 0 ? (x = a < 0 ? -1 : 1, y = 0, a < 0 ? -a : a) : (d = extgcd(b, a % b, y, x), y -= a / b * x, d); } ll modinv(ll a, ll mod) { ll x, y; extgcd(a, mod, x, y); if(x < 0) x += mod; return x; } ll modpow(ll a, ll b, ll mod) { ll r = 1; a %= mod; while(b) { if(b & 1) r = r * a % mod; a = a * a % mod; b >>= 1; } return r; } /// }}}--- /// // mult(a, b), makeE(n), pow(a, k) /// --- Matrix mult pow Library {{{ /// #include template < class T > std::vector< std::vector< T > > mult(std::vector< std::vector< T > > a, std::vector< std::vector< T > > b) { assert(a[0].size() == b.size()); std::vector< std::vector< T > > res(a.size(), std::vector< T >(b[0].size(), 0)); for(std::size_t i = 0; i < a.size(); i++) { for(std::size_t j = 0; j < b[0].size(); j++) { for(std::size_t k = 0; k < b.size(); k++) { res[i][j] += a[i][k] * b[k][j]; } } } return res; } template < class T > std::vector< std::vector< T > > makeE(std::size_t n) { std::vector< std::vector< T > > r(n, std::vector< T >(n, 0)); for(std::size_t i = 0; i < n; i++) r[i][i] = 1; return r; } template < class T > std::vector< std::vector< T > > pow(std::vector< std::vector< T > > a, unsigned long long k) { assert(a.size() == a[0].size()); std::vector< std::vector< T > > r = makeE< T >(a.size()); while(k) { if(k & 1) r = mult(r, a); a = mult(a, a); k >>= 1; } return r; } /// }}}--- /// // using Vec = std::vector< modint >; // using Mat = std::vector< Vec >; using Vec = vector; using Mat = vector; Mat inv2(Mat v) { Mat r(2, Vec(2)); // ad - bc double k = v[0][0] * v[1][1] - v[0][1] * v[1][0]; r[0][0] = v[1][1] / k; r[1][1] = v[0][0] / k; r[0][1] = -v[0][1] / k; r[1][0] = -v[1][0] / k; return r; } ll x[112345], y[112345]; int main() { std::ios::sync_with_stdio(false), std::cin.tie(0); ll a, b, c, d; cin >> a >> b >> c >> d; if(a > c) swap(a, c), swap(b, d); int n; cin >> n; for(int i = 0; i < n; i++) { cin >> x[i] >> y[i]; } // a/b == c/d if(a * d == c * b) { ll dx = a != 0 || c != 0 ? gcd(a, c) : gcd(b, d); ll dy = b * a / dx; int ans = 0; // dx * y切片 で分ける set st; for(int i = 0; i < n; i++) { st.emplace(dx * y[i] - dy * x[i]); } ans = st.size(); cout << ans << endl; return 0; } Mat v{{a, c}, {b, d}}; Mat w = inv2(v); // dump(w); // dump(floor(-.5)); set> st; constexpr double EPS = 1e-9; cout << fixed << setprecision(20); for(int i = 0; i < n; i++) { // dump(i); Mat z({{x[i]}, {y[i]}}); Mat t = mult(w, z); double k1 = t[0][0] - floor(t[0][0]), k2 = t[1][0] - floor(t[1][0]); ll l1 = floor(t[0][0]), l2 = floor(t[1][0]); // if(k1 > 1 - EPS) k1 -= 1, l1++; // if(k2 > 1 - EPS) k2 -= 1, l2++; // if(k1 < -1 + EPS) k1 += 1, l1--; // if(k2 < -1 + EPS) k2 += 1, l2--; double xx = 0, yy = 0; xx = k1 * a + k2 * c; yy = k1 * b + k2 * d; // dump(t); // dump(z); dump(k1, k2); dump(i); // dump(xx, yy); auto p = make_pair(round(xx), round(yy)); if(p == make_pair(a, b) || p == make_pair(c, d)) p = make_pair(0, 0); st.emplace(p); // dump(p); // assert(p.first + l1 * a + l2 * c == x[i]); // assert(p.second + l1 * b + l2 * d == y[i]); } // dump(st); cout << st.size() << endl; return 0; }