結果
問題 | No.2406 Difference of Coordinate Squared |
ユーザー |
![]() |
提出日時 | 2023-08-05 10:52:39 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
RE
|
実行時間 | - |
コード長 | 4,696 bytes |
コンパイル時間 | 1,886 ms |
コンパイル使用メモリ | 200,868 KB |
最終ジャッジ日時 | 2025-02-15 23:30:08 |
ジャッジサーバーID (参考情報) |
judge5 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 8 WA * 1 RE * 46 |
ソースコード
#line 1 "b.cpp" #include "bits/stdc++.h" using namespace std; namespace util { using ll = long long; using vl = std::vector<long long>; using pl = std::pair<long long, long long>; } // namespace util using namespace util; #include <atcoder/modint> #line 1 "cp-library/binomial.hpp" #include <cassert> #include <vector> template <typename T> class Binomial { private: int size_, mod_; std::vector<T> fact_, fact_inv_, inv_; public: explicit Binomial(int size) : size_(size), mod_(T::mod()) { fact_.resize(size + 1); fact_inv_.resize(size + 1); inv_.resize(size + 1); fact_[0] = fact_[1] = 1; fact_inv_[0] = fact_inv_[1] = 1; inv_[1] = 1; for (int i = 2; i <= size; ++i) { fact_[i] = fact_[i - 1] * i; inv_[i] = T(mod_) - inv_[mod_ % i] * (mod_ / i); fact_inv_[i] = fact_inv_[i - 1] * inv_[i]; } } T Calc(int n, int k) { assert(n <= size_ && k <= size_); if (k < 0 || n < 0 || n < k) return 0; if (k == 0) { return 1; } return fact_[n] * fact_inv_[n - k] * fact_inv_[k]; } T Factorial(int k) { assert(k >= 0 && k <= size_); return fact_[k]; } T FactorialInv(int k) { assert(k >= 0 && k <= size_); return fact_inv_[k]; } }; #line 2 "cp-library/cutils.hpp" #include <cmath> constexpr long long kMax = std::numeric_limits<long long>::max(); inline long long CountDigit(long long n, const long long base = 10) { assert(n > 0); assert(base > 1); long long res = 0; while (n) { res++; n /= base; } return res; } // verified inline long long Pow(long long x, long long n) { assert(n >= 0); if (x == 0) return 0; long long res = 1LL; while (n > 0) { if (n & 1) { assert(x != 0 && std::abs(res) <= kMax / std::abs(x)); res = res * x; } if (n >>= 1) { assert(x != 0 && std::abs(x) <= kMax / std::abs(x)); x = x * x; } } return res; } // verified inline long long Mod(long long n, const long long m) { // returns the "arithmetic modulo" // for a pair of integers (n, m) with m != 0, there exists a unique pair of // integer (q, r) s.t. n = qm + r and 0 <= r < |m| returns this r assert(m != 0); if (m < 0) return Mod(n, -m); if (n >= 0) return n % m; else return (m + n % m) % m; } inline long long Quotient(long long n, long long m) { // returns the "arithmetic quotient" assert((n - Mod(n, m)) % m == 0); return (n - Mod(n, m)) / m; } inline long long DivFloor(long long n, long long m) { // returns floor(n / m) assert(m != 0); if (m < 0) { n = -n; m = -m; } if (n >= 0) return n / m; else if (n % m == 0) return -(std::abs(n) / m); else return -(std::abs(n) / m) - 1; } inline long long DivCeil(long long n, long long m) { // returns ceil(n / m) assert(m != 0); if (n % m == 0) return DivFloor(n, m); else return DivFloor(n, m) + 1; } inline long long PowMod(long long x, long long n, const long long m) { assert(n >= 0); assert(m != 0); if (x == 0) return 0; long long res = 1; x = Mod(x, m); while (n > 0) { if (n & 1) { assert(x == 0 || std::abs(res) <= kMax / std::abs(x)); res = Mod(res * x, m); } if (n >>= 1) { assert(x == 0 || std::abs(x) <= kMax / std::abs(x)); x = Mod(x * x, m); } } return res; } long long SqrtFloor(long long n) { // n -> floor(sqrt(n)) assert(n >= 0); if (n == 0) return 0; long long ok = 0; long long ng = n + 1; while (ng - ok > 1) { long long mid = (ok + ng) / 2; if (mid <= n / mid) { ok = mid; } else { ng = mid; } } return ok; } long long SqrtCeil(long long n) { // n -> ceil(sqrt(n)) assert(n >= 0); if (n == 0) return 0; long long ok = n; long long ng = 0; while (ok - ng > 1) { long long mid = (ok + ng) / 2; if (mid >= n / mid) { ok = mid; } else { ng = mid; } } return ok; } #line 14 "b.cpp" using namespace atcoder; using mint = modint998244353; void solve() { ll n, m; cin >> n >> m; mint ans = 0; Binomial<mint> binom(n + 1); for (ll y = -n; y <= n; ++y) { if (m + y * y < 0) continue; if (SqrtCeil(m + y * y) != SqrtFloor(m + y * y)) continue; ll x = SqrtCeil(m + y * y); if ((x + y + n) % 2) continue; ans += binom.Calc(n, (x + y + n) / 2) * binom.Calc(n, (x - y + n) / 2); if (x != 0) { ans += binom.Calc(n, (-x + y + n) / 2) * binom.Calc(n, (-x - y + n) / 2); } } ans *= mint(4).inv().pow(n); cout << ans.val() << '\n'; } int main() { std::cin.tie(nullptr); std::ios::sync_with_stdio(false); std::cout << std::fixed << std::setprecision(15); solve(); return 0; }