結果
| 問題 | No.2280 FizzBuzz Difference | 
| コンテスト | |
| ユーザー |  Forested | 
| 提出日時 | 2023-04-21 22:12:38 | 
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) | 
| 結果 | 
                                AC
                                 
                             | 
| 実行時間 | 19 ms / 2,000 ms | 
| コード長 | 5,561 bytes | 
| コンパイル時間 | 1,327 ms | 
| コンパイル使用メモリ | 127,008 KB | 
| 最終ジャッジ日時 | 2025-02-12 11:47:32 | 
| ジャッジサーバーID (参考情報) | judge5 / judge2 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 1 | 
| other | AC * 7 | 
ソースコード
#ifndef LOCAL
#define FAST_IO
#endif
#define INT128
// ============
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#define OVERRIDE(a, b, c, d, ...) d
#define REP2(i, n) for (i32 i = 0; i < (i32)(n); ++i)
#define REP3(i, m, n) for (i32 i = (i32)(m); i < (i32)(n); ++i)
#define REP(...) OVERRIDE(__VA_ARGS__, REP3, REP2)(__VA_ARGS__)
#define PER(i, n) for (i32 i = (i32)(n) - 1; i >= 0; --i)
#define ALL(x) begin(x), end(x)
using namespace std;
using u32 = unsigned int;
using u64 = unsigned long long;
using i32 = signed int;
using i64 = signed long long;
using f64 = double;
using f80 = long double;
template <typename T>
using Vec = vector<T>;
template <typename T>
bool chmin(T &x, const T &y) {
    if (x > y) {
        x = y;
        return true;
    }
    return false;
}
template <typename T>
bool chmax(T &x, const T &y) {
    if (x < y) {
        x = y;
        return true;
    }
    return false;
}
template <typename T>
Vec<tuple<i32, i32, T>> runlength(const Vec<T> &a) {
    if (a.empty()) {
        return Vec<tuple<i32, i32, T>>();
    }
    Vec<tuple<i32, i32, T>> ret;
    i32 prv = 0;
    REP(i, 1, a.size()) {
        if (a[i - 1] != a[i]) {
            ret.emplace_back(prv, i, a[i - 1]);
            prv = i;
        }
    }
    ret.emplace_back(prv, (i32)a.size(), a.back());
    return ret;
}
#ifdef INT128
using u128 = __uint128_t;
using i128 = __int128_t;
istream &operator>>(istream &is, i128 &x) {
    i64 v;
    is >> v;
    x = v;
    return is;
}
ostream &operator<<(ostream &os, i128 x) {
    os << (i64)x;
    return os;
}
istream &operator>>(istream &is, u128 &x) {
    u64 v;
    is >> v;
    x = v;
    return is;
}
ostream &operator<<(ostream &os, u128 x) {
    os << (u64)x;
    return os;
}
#endif
[[maybe_unused]] constexpr i32 INF = 1000000100;
[[maybe_unused]] constexpr i64 INF64 = 3000000000000000100;
struct SetUpIO {
    SetUpIO() {
#ifdef FAST_IO
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
#endif
        cout << fixed << setprecision(15);
    }
} set_up_io;
// ============
#ifdef DEBUGF
#else
#define DBG(x) (void)0
#endif
#include <atcoder/math>
// ============
constexpr bool is_prime(unsigned n) {
    if (n == 0 || n == 1) {
        return false;
    }
    for (unsigned i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}
constexpr unsigned mod_pow(unsigned x, unsigned y, unsigned mod) {
    unsigned ret = 1, self = x;
    while (y != 0) {
        if (y & 1) {
            ret = (unsigned) ((unsigned long long) ret * self % mod);
        }
        self = (unsigned) ((unsigned long long) self * self % mod);
        y /= 2;
    }
    return ret;
}
template <unsigned mod>
constexpr unsigned primitive_root() {
    static_assert(is_prime(mod), "`mod` must be a prime number.");
    if (mod == 2) {
        return 1;
    }
    unsigned primes[32] = {};
    int it = 0;
    {
        unsigned m = mod - 1;
        for (unsigned i = 2; i * i <= m; ++i) {
            if (m % i == 0) {
                primes[it++] = i;
                while (m % i == 0) {
                    m /= i;
                }
            }
        }
        if (m != 1) {
            primes[it++] = m;
        }
    }
    for (unsigned i = 2; i < mod; ++i) {
        bool ok = true;
        for (int j = 0; j < it; ++j) {
            if (mod_pow(i, (mod - 1) / primes[j], mod) == 1) {
                ok = false;
                break;
            }
        }
        if (ok)
            return i;
    }
    return 0;
}
// y >= 1
template <typename T>
constexpr T safe_mod(T x, T y) {
    x %= y;
    if (x < 0) {
        x += y;
    }
    return x;
}
// y != 0
template <typename T>
constexpr T floor_div(T x, T y) {
    if (y < 0) {
        x *= -1;
        y *= -1;
    }
    if (x >= 0) {
        return x / y;
    } else {
        return -((-x + y - 1) / y);
    }
}
// y != 0
template <typename T>
constexpr T ceil_div(T x, T y) {
    if (y < 0) {
        x *= -1;
        y *= -1;
    }
    if (x >= 0) {
        return (x + y - 1) / y;
    } else {
        return -(-x / y);
    }
}
// ============
// count (x, y) s.t. a * x + b * y = k and lw <= x <= hi
i64 count_ans(i64 a, i64 b, i64 k, i64 lw, i64 hi) {
    if (lw > hi) {
        return 0;
    }
    i64 g = gcd(a, b);
    if (k % g != 0) {
        return 0;
    }
    a /= g;
    b /= g;
    k /= g;
    if (b < 0) {
        a *= -1;
        b *= -1;
        k *= -1;
    }
    // a * x + b * y = k
    // a * x = k (mod b)
    // x = k * inv(a) (mod b)
    i64 x = safe_mod(atcoder::inv_mod(a, b) * k, b);
    lw -= x;
    hi -= x;
    return floor_div(hi, b) - floor_div(lw - 1, b);
}
i64 solve(i64 m, i64 a, i64 b, i64 k) {
    if (k > a) {
        return 0;
    }
    if (k == a) {
        i64 as = m / a;
        i64 bs = as * a / b;
        i64 ls = as * a / lcm(a, b);
        i64 ans = as - 1 - (bs - ls);
        return ans;
    }
    i64 ans = count_ans(-a, b, k, 1, floor_div(m / b * b - k, a)) + count_ans(a, -b, k, ceil_div(b + k, a), m / a);
    return ans;
}
int main() {
    i32 t;
    cin >> t;
    while (t--) {
        i64 m, a, b, k;
        cin >> m >> a >> b >> k;
        cout << solve(m, a, b, k) << '\n';
    }
}
            
            
            
        