This documentation is automatically generated by online-judge-tools/verification-helper
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/problems/2609"
#include "../../Src/Template/IOSetting.hpp"
#include "../../Src/GeometryZ2/Point.hpp"
#include "../../Src/GeometryZ2/Circle.hpp"
#include "../../Src/Utility/BinarySearch.hpp"
using namespace zawa;
using namespace geometryZ2;
int main() {
SetFastIO();
Zahlen W, H, V, T, X, Y, P, Q;
std::cin >> W >> H >> V >> T >> X >> Y >> P >> Q;
Circle wave{Point{ X, Y }, V * T};
Zahlen ans{};
auto hito{[&](Zahlen x, Zahlen y) -> Point {
Point res{W * x, H * y};
res.x() += (x % 2 ? W - P : P);
res.y() += (y % 2 ? H - Q : Q);
return res;
}};
auto contains{[&](Zahlen x, Zahlen y) -> bool {
Point diff{wave.center() - hito(x, y)};
return !diff.isNormSquareOver(wave.radiusSquare());
}};
for (Zahlen x{-1000000} ; x <= 1000000 ; x++) {
if (!contains(x, 0)) continue;
ans += BinarySearch(Zahlen{1000000}, Zahlen{0}, [&](Zahlen y) -> bool {
return !contains(x, y);
});
ans -= BinarySearch(Zahlen{0}, Zahlen{-1000000}, [&](Zahlen y) -> bool {
return contains(x, y);
});
}
std::cout << ans << '\n';
}
#line 1 "Test/AOJ/2609.test.cpp"
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/problems/2609"
#line 2 "Src/Template/IOSetting.hpp"
#line 2 "Src/Template/TypeAlias.hpp"
#include <cstdint>
#include <cstddef>
namespace zawa {
using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;
using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using usize = std::size_t;
} // namespace zawa
#line 4 "Src/Template/IOSetting.hpp"
#include <iostream>
#include <iomanip>
namespace zawa {
void SetFastIO() {
std::cin.tie(nullptr)->sync_with_stdio(false);
}
void SetPrecision(u32 dig) {
std::cout << std::fixed << std::setprecision(dig);
}
} // namespace zawa
#line 2 "Src/GeometryZ2/Point.hpp"
#line 2 "Src/GeometryZ2/Zahlen.hpp"
#line 4 "Src/GeometryZ2/Zahlen.hpp"
#include <cassert>
namespace zawa {
namespace geometryZ2 {
using Zahlen = i64;
namespace internal {
constexpr i32 positive{1};
constexpr i32 zero{0};
constexpr i32 negative{-1};
} // namespace internal
constexpr i32 Sign(Zahlen value) {
if (value < 0) return internal::negative;
if (value > 0) return internal::positive;
return internal::zero;
}
constexpr bool Positive(Zahlen value) {
return Sign(value) == internal::positive;
}
constexpr bool Zero(Zahlen value) {
return Sign(value) == internal::zero;
}
constexpr bool Negative(Zahlen value) {
return Sign(value) == internal::negative;
}
constexpr Zahlen Abs(Zahlen value) {
return (value > 0 ? value : -value);
}
constexpr Zahlen Square(Zahlen value) {
return value * value;
}
} // namespace geometryZ2
} // namespace zawa
#line 5 "Src/GeometryZ2/Point.hpp"
#include <algorithm>
#line 9 "Src/GeometryZ2/Point.hpp"
#include <limits>
namespace zawa {
namespace geometryZ2 {
class Point {
private:
Zahlen x_{}, y_{};
static constexpr i32 origin{0};
static constexpr i32 firstQuadrant{1};
static constexpr i32 secondQuadrant{2};
static constexpr i32 thirdQuadrant{-2};
static constexpr i32 forthQuadrant{-1};
public:
/* constructor */
Point() = default;
Point(const Point& p) : x_{p.x()}, y_{p.y()} {}
Point(Zahlen x, Zahlen y) : x_{x}, y_{y} {}
/* getter setter */
Zahlen& x() {
return x_;
}
const Zahlen& x() const {
return x_;
}
Zahlen& y() {
return y_;
}
const Zahlen& y() const {
return y_;
}
/* operator */
Point& operator=(const Point& p) {
x() = p.x();
y() = p.y();
return *this;
}
Point& operator+=(const Point& p) {
x() += p.x();
y() += p.y();
return *this;
}
friend Point operator+(const Point& p0, const Point& p1) {
return Point{p0} += p1;
}
Point& operator-=(const Point& p) {
x() -= p.x();
y() -= p.y();
return *this;
}
friend Point operator-(const Point& p0, const Point& p1) {
return Point{p0} -= p1;
}
Point& operator*=(Zahlen k) {
x() *= k;
y() *= k;
return *this;
}
friend Point operator*(const Point& p, Zahlen k) {
return Point{p} *= k;
}
friend Point operator*(Zahlen k, const Point& p) {
return Point{p} *= k;
}
Point& operator/=(Zahlen k) {
assert(k);
assert(x() % k == 0);
assert(y() % k == 0);
x() /= k;
y() /= k;
return *this;
}
friend Point operator/(const Point& p, Zahlen k) {
return Point{p} /= k;
}
friend bool operator==(const Point& p0, const Point& p1) {
return p0.x() == p1.x() and p0.y() == p1.y();
}
friend bool operator!=(const Point& p0, const Point& p1) {
return p0.x() != p1.x() or p0.y() != p1.y();
}
friend bool operator<(const Point& p0, const Point& p1) {
if (p0.x() != p1.x()) return p0.x() < p1.x();
else return p0.y() < p1.y();
}
friend bool operator<=(const Point& p0, const Point& p1) {
return (p0 < p1) or (p0 == p1);
}
friend bool operator>(const Point& p0, const Point& p1) {
if (p0.x() != p1.x()) return p0.x() > p1.x();
else return p0.y() > p1.y();
}
friend bool operator>=(const Point& p0, const Point& p1) {
return (p0 > p1) or (p0 == p1);
}
friend std::istream& operator>>(std::istream& is, Point& p) {
is >> p.x() >> p.y();
return is;
}
friend std::ostream& operator<<(std::ostream& os, const Point& p) {
os << '(' << p.x() << ',' << p.y() << ')';
return os;
}
/* member function */
Zahlen normSquare() const {
return Square(x()) + Square(y());
}
bool isNormSquareOver(Zahlen d) const {
assert(!Negative(d));
auto [mn, mx]{std::minmax({ Abs(x()), Abs(y()) })};
if (mx and mx > d / mx) {
return true;
}
long long s1{Square(mn)}, s2{Square(mx)};
if (s1 > d - s2) {
return true;
}
return false;
}
bool isNormSquareOverflow() const {
return isNormSquareOver(std::numeric_limits<Zahlen>::max());
}
i32 area() const {
if (x_ == 0 and y_ == 0) return origin;
if (x_ <= 0 and y_ < 0) return thirdQuadrant;
if (x_ > 0 and y_ <= 0) return forthQuadrant;
if (x_ >= 0 and y_ > 0) return firstQuadrant;
return secondQuadrant;
}
/* static member */
static bool ArgComp(const Point& p0, const Point& p1) {
if (p0.area() != p1.area()) return p0.area() < p1.area();
Zahlen cross{Cross(p0, p1)};
return (!Zero(cross) ? Positive(cross) : p0.normSquare() < p1.normSquare());
}
/* friend function */
friend Zahlen Dot(const Point& p0, const Point& p1) {
return p0.x() * p1.x() + p0.y() * p1.y();
}
friend Zahlen Cross(const Point& p0, const Point& p1) {
return p0.x() * p1.y() - p0.y() * p1.x();
}
};
using Vector = Point;
} // namespace geometryZ2
} // namespace zawa
#line 2 "Src/GeometryZ2/Circle.hpp"
#line 2 "Src/GeometryZ2/Distance/PointAndPoint.hpp"
#line 5 "Src/GeometryZ2/Distance/PointAndPoint.hpp"
namespace zawa {
namespace geometryZ2 {
Zahlen DistanceSquare(const Point& p0, const Point& p1) {
return Vector{p1 - p0}.normSquare();
}
} // namespace geometryZ2
} // namespace zawa
#line 7 "Src/GeometryZ2/Circle.hpp"
#line 9 "Src/GeometryZ2/Circle.hpp"
namespace zawa {
namespace geometryZ2 {
class Circle {
private:
Point center_{};
Zahlen radius_{};
public:
/* constructor */
Circle() = default;
Circle(const Point& center, const Zahlen radius) : center_{center}, radius_{radius} {
assert(!Negative(radius_));
}
/* getter, setter */
Point& center() {
return center_;
}
const Point& center() const {
return center_;
}
Zahlen& radius() {
return radius_;
}
const Zahlen& radius() const {
return radius_;
}
/* operator */
Circle& operator=(const Circle& c) {
radius_ = c.radius();
center_ = c.center();
return *this;
}
friend bool operator==(const Circle& c0, const Circle& c1) {
return c0.radius() == c1.radius() and c0.center() == c1.center();
}
friend bool operator!=(const Circle& c0, const Circle& c1) {
return c0.radius() != c1.radius() or c0.center() != c1.center();
}
/* member */
Zahlen radiusSquare() const {
return Square(radius_);
}
/* friend function */
friend u32 NumberCommonTangent(const Circle& c0, const Circle& c1) {
Zahlen dist{DistanceSquare(c0.center(), c1.center())};
Zahlen down{Square(Abs(c0.radius() - c1.radius()))};
if (dist < down) {
return 0;
}
if (dist == down) {
return 1;
}
Zahlen up{Square(c0.radius() + c1.radius())};
if (dist < up) {
return 2;
}
if (dist == up) {
return 3;
}
return 4;
}
};
} // namespace geometryZ2
} // namespace zawa
#line 2 "Src/Utility/BinarySearch.hpp"
#line 4 "Src/Utility/BinarySearch.hpp"
#include <cmath>
#include <functional>
#include <type_traits>
#include <utility>
namespace zawa {
namespace internal {
template <class T>
T MidPoint(T a, T b) {
if (a > b) std::swap(a, b);
return a + ((b - a) >> 1);
}
template <class T>
T Abs(T a, T b) {
return (a >= b ? a - b : b - a);
}
} // namespace zawa::internal
template <class T, class Function>
T BinarySearch(T ok, T ng, const Function& f) {
static_assert(std::is_integral_v<T>, "T must be integral type");
static_assert(std::is_convertible_v<Function, std::function<bool(T)>>, "f must be function bool(T)");
while (internal::Abs(ok, ng) > 1) {
T mid{ internal::MidPoint(ok, ng) };
(f(mid) ? ok : ng) = mid;
}
return ok;
}
template <class T, class Function>
T BinarySearch(T ok, T ng, const Function& f, u32 upperLimit) {
static_assert(std::is_signed_v<T>, "T must be signed arithmetic type");
static_assert(std::is_convertible_v<Function, std::function<bool(T)>>, "f must be function bool(T)");
for (u32 _{} ; _ < upperLimit ; _++) {
T mid{ (ok + ng) / (T)2 };
(f(mid) ? ok : ng) = mid;
}
return ok;
}
} // namespace zawa
#line 7 "Test/AOJ/2609.test.cpp"
using namespace zawa;
using namespace geometryZ2;
int main() {
SetFastIO();
Zahlen W, H, V, T, X, Y, P, Q;
std::cin >> W >> H >> V >> T >> X >> Y >> P >> Q;
Circle wave{Point{ X, Y }, V * T};
Zahlen ans{};
auto hito{[&](Zahlen x, Zahlen y) -> Point {
Point res{W * x, H * y};
res.x() += (x % 2 ? W - P : P);
res.y() += (y % 2 ? H - Q : Q);
return res;
}};
auto contains{[&](Zahlen x, Zahlen y) -> bool {
Point diff{wave.center() - hito(x, y)};
return !diff.isNormSquareOver(wave.radiusSquare());
}};
for (Zahlen x{-1000000} ; x <= 1000000 ; x++) {
if (!contains(x, 0)) continue;
ans += BinarySearch(Zahlen{1000000}, Zahlen{0}, [&](Zahlen y) -> bool {
return !contains(x, y);
});
ans -= BinarySearch(Zahlen{0}, Zahlen{-1000000}, [&](Zahlen y) -> bool {
return contains(x, y);
});
}
std::cout << ans << '\n';
}