QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#842892#9962. Diminishing Fractionsucup-team5243#TL 1480ms4024kbC++1727.2kb2025-01-04 15:39:282025-01-04 15:39:29

Judging History

你现在查看的是最新测评结果

  • [2025-01-04 15:39:29]
  • 评测
  • 测评结果:TL
  • 用时:1480ms
  • 内存:4024kb
  • [2025-01-04 15:39:28]
  • 提交

answer

//#ifdef NACHIA
//#define _GLIBCXX_DEBUG
//#else
//#define NDEBUG
//#endif
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using i64 = long long;
using u64 = unsigned long long;
#define rep(i,n) for(int i=0; i<int(n); i++)
const i64 INF = 1001001001001001001;
template<typename A> void chmin(A& l, const A& r){ if(r < l) l = r; }
template<typename A> void chmax(A& l, const A& r){ if(l < r) l = r; }
using namespace std;

#include <cassert>
#include <utility>

namespace nachia{

// ax + by = gcd(a,b)
// return ( x, - )
std::pair<long long, long long> ExtGcd(long long a, long long b){
    long long x = 1, y = 0;
    while(b){
        long long u = a / b;
        std::swap(a-=b*u, b);
        std::swap(x-=y*u, y);
    }
    return std::make_pair(x, a);
}

} // namespace nachia

namespace nachia{

template<unsigned int MOD>
struct StaticModint{
private:
    using u64 = unsigned long long;
    unsigned int x;
public:

    using my_type = StaticModint;
    template< class Elem >
    static Elem safe_mod(Elem x){
        if(x < 0){
            if(0 <= x+MOD) return x + MOD;
            return MOD - ((-(x+MOD)-1) % MOD + 1);
        }
        return x % MOD;
    }

    StaticModint() : x(0){}
    StaticModint(const my_type& a) : x(a.x){}
    StaticModint& operator=(const my_type&) = default;
    template< class Elem >
    StaticModint(Elem v) : x(safe_mod(v)){}
    unsigned int operator*() const noexcept { return x; }
    my_type& operator+=(const my_type& r) noexcept { auto t = x + r.x; if(t >= MOD) t -= MOD; x = t; return *this; }
    my_type operator+(const my_type& r) const noexcept { my_type res = *this; return res += r; }
    my_type& operator-=(const my_type& r) noexcept { auto t = x + MOD - r.x; if(t >= MOD) t -= MOD; x = t; return *this; }
    my_type operator-(const my_type& r) const noexcept { my_type res = *this; return res -= r; }
    my_type operator-() const noexcept { my_type res = *this; res.x = ((res.x == 0) ? 0 : (MOD - res.x)); return res; }
    my_type& operator*=(const my_type& r)noexcept { x = (u64)x * r.x % MOD; return *this; }
    my_type operator*(const my_type& r) const noexcept { my_type res = *this; return res *= r; }
    my_type pow(unsigned long long i) const noexcept {
        my_type a = *this, res = 1;
        while(i){ if(i & 1){ res *= a; } a *= a; i >>= 1; }
        return res;
    }
    my_type inv() const { return my_type(ExtGcd(x, MOD).first); }
    unsigned int val() const noexcept { return x; }
    static constexpr unsigned int mod() { return MOD; }
    static my_type raw(unsigned int val) noexcept { auto res = my_type(); res.x = val; return res; }
    my_type& operator/=(const my_type& r){ return operator*=(r.inv()); }
    my_type operator/(const my_type& r) const { return operator*(r.inv()); }
};

} // namespace nachia

namespace nachia{

template<unsigned int MOD>
struct PrimitiveRoot{
    using u64 = unsigned long long;
    static constexpr u64 powm(u64 a, u64 i) {
        u64 res = 1, aa = a;
        for( ; i; i /= 2){
            if(i & 1) res = res * aa % MOD;
            aa = aa * aa % MOD;
        }
        return res;
    }
    static constexpr bool ExamineVal(unsigned int g){
        u64 t = MOD - 1;
        for(u64 d=2; d*d<=t; d+=1+(d&1)) if(t % d == 0){
            if(powm(g, (MOD - 1) / d) == 1) return false;
            while(t % d == 0) t /= d;
        }
        if(t != 1) if(powm(g, (MOD - 1) / t) == 1) return false;
        return true;
    }
    static constexpr unsigned int GetVal(){
        for(u64 x=2; x<MOD; x++) if(ExamineVal(x)) return x;
        return 0;
    }
    static const unsigned int val = GetVal();
};

} // namespace nachia

namespace nachia {

template<class mint>
struct NttInterface{

template<class Iter>
void Butterfly(Iter, int) const {}

template<class Iter>
void IButterfly(Iter, int) const {}

template<class Iter>
void BitReversal(Iter a, int N) const {
    for(int i=0, j=0; j<N; j++){
        if(i < j) std::swap(a[i], a[j]);
        for(int k = N>>1; k > (i^=k); k>>=1);
    }
}

};

} // namespace nachia

namespace nachia{

int Popcount(unsigned long long c) noexcept {
#ifdef __GNUC__
    return __builtin_popcountll(c);
#else
    c = (c & (~0ull/3)) + ((c >> 1) & (~0ull/3));
    c = (c & (~0ull/5)) + ((c >> 2) & (~0ull/5));
    c = (c & (~0ull/17)) + ((c >> 4) & (~0ull/17));
    c = (c * (~0ull/257)) >> 56;
    return c;
#endif
}

// please ensure x != 0
int MsbIndex(unsigned long long x) noexcept {
#ifdef __GNUC__
    return 63 - __builtin_clzll(x);
#else
    using u64 = unsigned long long;
    int q = (x >> 32) ? 32 : 0;
    auto m = x >> q;
    constexpr u64 hi = 0x88888888;
    constexpr u64 mi = 0x11111111;
    m = (((m | ~(hi - (m & ~hi))) & hi) * mi) >> 35;
    m = (((m | ~(hi - (m & ~hi))) & hi) * mi) >> 31;
    q += (m & 0xf) << 2;
    q += 0x3333333322221100 >> (((x >> q) & 0xf) << 2) & 0xf;
    return q;
#endif
}

// please ensure x != 0
int LsbIndex(unsigned long long x) noexcept {
#ifdef __GNUC__
    return __builtin_ctzll(x);
#else
    return MsbIndex(x & -x);
#endif
}

}

#include <iterator>
#include <array>

namespace nachia{

template <class mint>
struct NttFromAcl : NttInterface<mint> {

using u32 = unsigned int;
using u64 = unsigned long long;
    
static int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (u32)(n)) x++;
    return x;
}
    
static constexpr int bsf_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

struct fft_info {
    static constexpr u32 g = nachia::PrimitiveRoot<mint::mod()>::val;
    static constexpr int rank2 = bsf_constexpr(mint::mod()-1);
    using RootTable = std::array<mint, rank2+1>;
    RootTable root, iroot, rate3, irate3;

    fft_info(){
        root[rank2] = mint(g).pow((mint::mod() - 1) >> rank2);
        iroot[rank2] = root[rank2].inv();
        for(int i=rank2-1; i>=0; i--){
            root[i] = root[i+1] * root[i+1];
            iroot[i] = iroot[i+1] * iroot[i+1];
        }
        mint prod = 1, iprod = 1;
        for(int i=0; i<=rank2-3; i++){
            rate3[i] = root[i+3] * prod;
            irate3[i] = iroot[i+3] * iprod;
            prod *= iroot[i+3];
            iprod *= root[i+3];
        }
    }
};

template<class RandomAccessIterator>
void Butterfly(RandomAccessIterator a, int n) const {
    int h = ceil_pow2(n);

    static const fft_info info;

    int len = 0;
    if((h-len)%2 == 1){
        int p = 1 << (h-len-1);
        for(int i=0; i<p; i++){
            mint l = a[i], r = a[i+p];
            a[i] = l+r; a[i+p] = l-r;
        }
        len++;
    }
    for( ; len < h; len += 2){
        int p = 1 << (h-len-2);
        mint rot = 1, imag = info.root[2];
        u64 mod2 = u64(mint::mod()) * mint::mod();
        for(int s=0; s<(1<<len); s++){
            if(s) rot *= info.rate3[LsbIndex(~(u32)(s-1))];
            mint rot2 = rot * rot;
            mint rot3 = rot2 * rot;
            int offset = (s << (h-len)) + p;
            for(int i=offset-p; i<offset; i++){
                u64 a0 = u64(a[i].val());
                u64 a1 = u64(a[i+p].val()) * rot.val();
                u64 a2 = u64(a[i+2*p].val()) * rot2.val();
                u64 a3 = u64(a[i+3*p].val()) * rot3.val();
                u64 a1na3imag = u64(mint(a1 + mod2 - a3).val()) * imag.val();
                u64 na2 = mod2 - a2;
                a[i] = a0 + a2 + a1 + a3;
                a[i+1*p] = a0 + a2 + (2 * mod2 - (a1 + a3));
                a[i+2*p] = a0 + na2 + a1na3imag;
                a[i+3*p] = a0 + na2 + (mod2 - a1na3imag);
            }
        }
    }
}

template<class RandomAccessIterator>
void IButterfly(RandomAccessIterator a, int n) const {
    int h = ceil_pow2(n);

    static const fft_info info;
    constexpr int MOD = mint::mod();

    int len = h;
    for( ; 1 < len; len -= 2){
        int p = 1 << (h-len);
        mint irot = 1, iimag = info.iroot[2];
        for(int s=0; s<(1<<(len-2)); s++){
            if(s) irot *= info.irate3[LsbIndex(~(u32)(s-1))];
            mint irot2 = irot * irot;
            mint irot3 = irot2 * irot;
            int offset = (s << (h-len+2)) + p;
            for(int i=offset-p; i<offset; i++){
                u64 a0 = a[i].val();
                u64 a1 = a[i+p].val();
                u64 a2 = a[i+2*p].val();
                u64 a3 = a[i+3*p].val();
                u64 a2na3iimag = mint((a2 + MOD - a3) * iimag.val()).val();
                a[i] = a0 + a1 + a2 + a3;
                a[i+p] = (a0 + (MOD - a1) + a2na3iimag) * irot.val();
                a[i+2*p] = (a0 + a1 + (MOD - a2) + (MOD - a3)) * irot2.val();
                a[i+3*p] = (a0 + (MOD - a1) + (MOD - a2na3iimag)) * irot3.val();
            }
        }
    }
    if(len == 1){
        int p = 1 << (h-len);
        for(int i=0; i<p; i++){
            mint l = a[i], r = a[i+p];
            a[i] = l+r; a[i+p] = l-r;
        }
    }
}

};

} // namespace nachia

namespace nachia {

struct BigintDecMulManager {
    using Int = int;
    using Arr = std::vector<Int>;
    using u32 = unsigned int;
    using i64 = long long;
    static const Int B = 1000000000;
    static const u32 MOD0 = 0x1c000001;
    static const u32 MOD1 = 0x6c000001;
    static const u32 MOD2 = 0x78000001;
    static const u32 I0_M1 = 1540148431;
    static const u32 I01_M2 = 1050399624;
    static const u32 I1_M2 = 10;
    static const u32 IB_M1 = 1575545083;
    static const u32 IB_M2 = 65929464;

    template<u32 MOD>
    static std::vector<u32> convMod(int z, int n, const Arr& a, const Arr& b){
        using Mint = StaticModint<MOD>;
        static auto ntt = NttFromAcl<Mint>();
        std::vector<Mint> a2(z);
        for(int i=0; i<(int)a.size(); i++) a2[i] = a[i];
        std::vector<Mint> b2(z);
        for(int i=0; i<(int)b.size(); i++) b2[i] = b[i];
        Mint c = Mint(z).inv();
        ntt.Butterfly(a2.begin(), z);
        ntt.Butterfly(b2.begin(), z);
        for(int i=0; i<z; i++) a2[i] *= b2[i] * c;
        ntt.IButterfly(a2.begin(), z);
        std::vector<u32> res(n);
        for(int i=0; i<n; i++) res[i] = a2[i].val();
        return res;
    }
    template<u32 M>
    static inline StaticModint<M> SubMod(u32 a, u32 b){
        return StaticModint<M>::raw(a<b ? a+M-b : a-b);
    }

    static Arr BigintDecMul(const Arr& a, const Arr& b){
        int n = a.size() + b.size();
        int n2 = 1; while(n2 < n) n2 *= 2;
        auto c0 = convMod<MOD0>(n2, n-1, a, b);
        auto c1 = convMod<MOD1>(n2, n-1, a, b);
        auto c2 = convMod<MOD2>(n2, n-1, a, b);
        std::vector<i64> c(n+1);
        using MintB = StaticModint<B>;
        using Mint1 = StaticModint<MOD1>;
        using Mint2 = StaticModint<MOD2>;
        auto i0m1 = Mint1::raw(I0_M1);
        auto i01m2 = Mint2::raw(I01_M2);
        auto ibm1 = Mint1::raw(IB_M1);
        auto ibm2 = Mint2::raw(IB_M2);
        auto i1m2 = Mint2::raw(I1_M2);
        auto m01_b = MintB::raw(MOD0) * MintB(MOD1);
        for(int i=0; i<n-1; i++){
            u32 d0to1 = (i0m1 * SubMod<MOD1>(c1[i], c0[i])).val();
            Mint2 x01m2 = Mint2::raw(c0[i]) + Mint2::raw(MOD0) * Mint2::raw(d0to1);
            MintB x01mB = MintB::raw(c0[i]) + MintB::raw(MOD0) * MintB(d0to1);
            MintB xmB = x01mB + m01_b * MintB((i01m2 * SubMod<MOD2>(c2[i], x01m2.val())).val());
            c[i] += xmB.val();
            Mint1 y1 = SubMod<MOD1>(c1[i], xmB.val()) * ibm1;
            Mint2 y2 = SubMod<MOD2>(c2[i], xmB.val()) * ibm2;
            i64 y12 = (i64)y1.val() + (i64)MOD1 * (i64)(i1m2 * SubMod<MOD2>(y2.val(), y1.val())).val();
            c[i+1] += y12 % B; c[i+2] += y12 / B;
        }
        Arr res(n);
        for(int i=0; i<n; i++){
            res[i] = c[i]%B;
            c[i+1] += c[i]/B;
        }
        if(res.back() == 0) res.pop_back();
        return res;
    }

};

};


namespace nachia {

struct BigintDec{
    using Int = int;
    using Arr = std::vector<Int>;

    BigintDec() : sign(0), A(0) {}
    BigintDec(int z){
        if(z == 0){ sign = 0; }
        else if(z < 0){ sign = -1; A = Arr(1, -z); }
        else{ sign = 1; A = Arr(1, z); }
    }
    BigintDec(const std::string& s) : sign(1) {
        auto it = s.begin();
        if(it != s.end()){
            if(*it == '-'){ sign = -1; it++; }
            else if(*it == '+'){ it++; }
        }
        while(it != s.end() && *it == '0') it++;
        if(it == s.end()){ sign = 0; }
        else {
            auto f = (s.end() - it);
            int e = int((f-1) / 9);
            int d = int((f-1) % 9);
            A.assign(e + 1, 0);
            for( ; it!=s.end(); it++){
                assert('0' <= *it && *it <= '9');
                A[e] = A[e] * 10 + (*it - '0');
                d--; if(d < 0){ d = 8; e -= 1; }
            }
        }
    }

    BigintDec operator+(const BigintDec& r) const {
        if(r.isZero()) return *this;
        if(isZero()) return r;
        auto x = (sign == r.sign) ?
            uintSum(*this, r) : uintDiff(*this, r);
        x.sign *= sign;
        return x;
    }

    BigintDec operator-() const { return raw(-sign, A); }

    BigintDec operator-(const BigintDec& r) const {
        if(r.isZero()) return *this;
        if(isZero()) return -r;
        auto x = (sign == r.sign) ?
            uintDiff(*this, r) : uintSum(*this, r);
        x.sign *= sign;
        return x;
    }

    BigintDec operator*(const BigintDec& r) const {
        if(isZero() || r.isZero()) return Zero();
        return raw(sign * r.sign, uintMul(*this, r));
    }

    std::pair<BigintDec, BigintDec> divrem(const BigintDec& r) const {
        assert(!r.isZero());
        if(isZero() || CmpAbs(*this, r) == 1) return { Zero(), *this };
        auto invr = r.invFlex(len()+1);
        auto a2 = (*this * invr).shiftRight(len() + r.len() + 2);
        a2.sign = sign * r.sign;
        auto rem = (*this) - (r * a2);
        if(CmpAbs(r, rem) >= 0){
            rem = rem - r;
            a2 = a2 + BigintDec("1");
        }
        return std::make_pair(std::move(a2), std::move(rem));
    }

    BigintDec operator/(const BigintDec& r){
        assert(!r.isZero());
        return divrem(r).first;
    }

    BigintDec& operator*=(int x){
        if(x == 0) return (*this) = Zero();
        i64 y = std::abs(x);
        i64 c = 0;
        for(int i=0; i<len(); i++){
            c += A[i] * y;
            A[i] = c % B; c /= B;
        }
        if(c >= B){ A.push_back(c % B); c /= B; }
        if(c) A.push_back(c);
        if(x < 0) sign = -sign;
        return *this;
    }

    static BigintDec Zero(){ return BigintDec(); }
    bool isZero() const { return sign == 0; }
    std::string toString() const {
        if(isZero()) return "0";
        std::string s;
        for(int i=0; i<len()-1; i++){
            int a = A[i];
            for(int d=0; d<9; d++){ s.push_back('0'+a%10); a /= 10; }
        }
        for(Int a=A[len()-1]; a!=0; a/=10) s.push_back('0'+a%10);
        if(sign < 0) s.push_back('-');
        std::reverse(s.begin(), s.end());
        return s;
    }
    bool operator<(const BigintDec& r) const {
        if(sign != r.sign) return sign < r.sign;
        return CmpAbs(*this, r) == sign;
    }
    bool operator>(const BigintDec& r) const { return r < *this; }
    bool operator<=(const BigintDec& r) const { return !(r < *this); }
    bool operator>=(const BigintDec& r) const { return !(*this < r); }
    bool operator==(const BigintDec& r) const { return sign == r.sign && A == r.A; }
    bool operator!=(const BigintDec& r) const { return !(*this == r); }
private:
    using Self = BigintDec;
    using i64 = long long;
    int sign;
    std::vector<Int> A;
    static const int B = 1000000000;
    int len() const { return int(A.size()); }
    Int dig(int z) const { return z < len() ? A[z] : 0; }
    Int& operator[](int z){ return A[z]; }
    const Int& operator[](int z) const { return A[z]; }
    static int CmpUintPos(const Self& l, const Self& r){
        if(l.len() != r.len()) return std::max(l.len(), r.len()) - 1;
        for(int i=l.len()-1; i>=0; i--) if(l[i] != r[i]) return i;
        return -1;
    }
    static int CmpAbs(const Self& l, const Self& r){
        int k = CmpUintPos(l, r);
        if(k < 0) return 0;
        return l.dig(k) < r.dig(k) ? 1 : -1;
    }
    static Self raw(int sign, Arr a){
        if(a.empty()) sign = 0;
        while(!a.empty() && a.back() == 0) a.pop_back();
        Self res; res.sign = sign; res.A = std::move(a);
        return res;
    }
    static Self uintDiff2(const Self& l, const Self& r, int k){
        Arr A(k + 1);
        for(int i=0; i<=k; i++) A[i] = l[i];
        int j = std::min(k+1, r.len());
        Int v = 0;
        for(int i=0; i<j; i++){
            v = v + A[i] - r[i];
            if(v < 0){ A[i] = v + B; v = -1; }
            else { A[i] = v; v = 0; }
        }
        for(int i=j; v!=0; i++){
            v = v + A[i];
            if(v < 0){ A[i] = v + B; v = -1; }
            else { A[i] = v; v = 0; }
        }
        return raw(1, std::move(A));
    }
    static Self uintDiff(const Self& l, const Self& r){
        int k = CmpUintPos(l, r);
        if(k == -1) return Zero();
        if(l.dig(k) > r.dig(k)) return uintDiff2(l, r, k);
        auto x = uintDiff2(r, l, k); x.sign = -x.sign;
        return x;
    }
    static Self uintSum(const Self& l, const Self& r){
        if(l.len() > r.len()) return uintSum(r, l);
        Arr A(r.len() + 1);
        for(int i=0; i<l.len(); i++) A[i] = l[i];
        Int v = 0;
        for(int i=0; i<r.len(); i++){
            v = v + A[i] + r[i];
            if(B <= v){ A[i] = v - B; v = 1; }
            else { A[i] = v; v = 0; }
        }
        if(v != 0) A[r.len()] = v; else A.pop_back();
        return raw(1, std::move(A));
    }
    static Arr uintMul(const Self& l, const Self& r){
        if(l.len() >= 30 && r.len() >= 30){
            return BigintDecMulManager::BigintDecMul(l.A, r.A);
        }
        int z = l.len() + r.len();
        Arr a(z);
        for(int i=0; i<l.len(); i++) for(int j=0; j<r.len(); j++){
            i64 x = (i64)(l[i]) * r[j] + a[i+j];
            a[i+j] = x % B; a[i+j+1] += x / B;
        }
        if(a.back() == 0) a.pop_back();
        return a;
    }
    Self shiftLeft(int delta) const {
        if(isZero()) return Zero();
        Arr a(len() + delta);
        for(int i=0; i<len(); i++) a[i+delta] = A[i];
        return raw(sign, std::move(a));
    }
    Self shiftRight(int delta) const {
        if(len() <= delta) return Zero();
        Arr a(len() - delta);
        for(int i=delta; i<len(); i++) a[i-delta] = A[i];
        return raw(sign, std::move(a));
    }
    Self shiftToLength(int tg) const {
        return len() < tg ? shiftLeft(tg - len())
            : shiftRight(len() - tg);
    }
    void negate(){ sign = -sign; }
    Self invFlex(int prec) const {
        Int t = B / (A[len()-1] + 1);
        auto a2 = *this; a2 *= t;
        auto b2 = a2.invPrec(prec);
        b2 *= t;
        return b2;
    }
    Self invPrec(int prec){
        if(prec == 1){
            Int b = A[len()-1];
            Arr a(3); a[2] = 1; a[1] = i64(B) * B / b - B;
            return raw(sign, std::move(a));
        }
        int subp = (prec + 1) / 2;
        auto b = invPrec(subp);
        auto ab = (shiftToLength(prec+1) * b).shiftRight(subp+1);
        auto ab2 = Self("2").shiftLeft(prec+1) - ab;
        return (ab2 * b).shiftRight(subp + 1);
    }
};

}

namespace {

std::istream& operator>>(std::istream& i, nachia::BigintDec& d){
    std::string s; i >> s;
    d = nachia::BigintDec(s);
    return i;
}

std::ostream& operator<<(std::ostream& o, const nachia::BigintDec& d){
    return o << d.toString();
}

}




namespace nachia{

namespace prime_sieve_explicit_internal{
    std::vector<bool> isprime = { false }; // a[x] := isprime(2x+1)

    void CalcIsPrime(int z){
        if((int)isprime.size() *2+1 < z+1){
            int new_z = isprime.size();
            while(new_z*2+1 < z+1) new_z *= 2;
            z = new_z-1;
            isprime.resize(z+1, true);
            for(int i=1; i*(i+1)*2<=z; i++) if(isprime[i]){
                for(int j=i*(i+1)*2; j<=z; j+=i*2+1) isprime[j] = false;
            }
        }
    }
    
    std::vector<int> prime_list = {2};
    int prime_list_max = 0;

    void CalcPrimeList(int z){
        while((int)prime_list.size() < z){
            if((int)isprime.size() <= prime_list_max + 1) CalcIsPrime(prime_list_max * 2 + 10);
            for(int p=prime_list_max+1; p<(int)isprime.size(); p++){
                if(isprime[p]) prime_list.push_back(p*2+1);
            }
            prime_list_max = isprime.size() - 1;
        }
    }

    void CalcPrimeListUntil(int z){
        if(prime_list_max < z){
            CalcIsPrime(z);
            for(int p=prime_list_max+1; p<(int)isprime.size(); p++){
                if(isprime[p]) prime_list.push_back(p*2+1);
            }
            prime_list_max = isprime.size() - 1;
        }
    }

}


bool IsprimeExplicit(int n){
    using namespace prime_sieve_explicit_internal;
    if(n == 2) return true;
    if(n % 2 == 0) return false;
    CalcIsPrime(n);
    return isprime[(n-1)/2];
}

int NthPrimeExplicit(int n){
    using namespace prime_sieve_explicit_internal;
    CalcPrimeList(n);
    return prime_list[n];
}

int PrimeCountingExplicit(int n){
    using namespace prime_sieve_explicit_internal;
    if(n < 2) return 0;
    CalcPrimeListUntil(n);
    auto res = std::upper_bound(prime_list.begin(), prime_list.end(), n) - prime_list.begin();
    return (int)res;
}

// [l, r)
std::vector<bool> SegmentedSieveExplicit(long long l, long long r){
    assert(0 <= l); assert(l <= r);
    long long d = r - l;
    if(d == 0) return {};
    std::vector<bool> res(d, true);
    for(long long p=2; p*p<=r; p++) if(IsprimeExplicit(p)){
        long long il = (l+p-1)/p, ir = (r+p-1)/p;
        if(il <= p) il = p;
        for(long long i=il; i<ir; i++) res[i*p-l] = false;
    }
    if(l < 2) for(long long p=l; p<2 && p<r; p++) res[l-p] = false;
    return res;
}


} // namespace nachia

namespace nachia{

class DynamicModSupplier{
    using u64 = unsigned long long;
    using Int = unsigned int;
private:
    u64 imod;
    Int mod;
    // atcoder library
    u64 reduce2(u64 z) const noexcept {
        // atcoder library
#ifdef _MSC_VER
        u64 x; _umul128(z, im, &x);
#else
        using u128 = unsigned __int128;
        u64 x = (u64)(((u128)(z)*imod) >> 64);
#endif
        return z - x * mod;
    }
public:
    DynamicModSupplier(unsigned int MOD = 998244353) : mod(MOD) {
        assert(2 <= MOD);
        assert(MOD < (1u << 31));
        imod = (u64)(-1) / mod + 1;
    }
    Int reduce(u64 z) const noexcept {
        Int v = reduce2(z);
        if(mod <= v) v += mod;
        return v;
    }
    Int add(Int a, Int b) const { a += b; if(a >= mod){ a -= mod; } return a; }
    Int sub(Int a, Int b) const { a -= b; if(a >= mod){ a += mod; } return a; }
    Int mul(Int a, Int b) const { return reduce((u64)a * b); }
    Int muladd(Int a, Int b, Int c) const { return reduce((u64)a * b + c); }
    Int inv(Int a) const {
        Int v = ExtGcd(a, mod).first;
        return (v < mod) ? v : (v + mod);
    }
    Int pow(Int a, u64 i) const {
        Int r = a, ans = 1;
        while(i){
            if(i & 1) ans = mul(ans, r);
            i /= 2;
            r = mul(r, r);
        }
        return ans;
    }
    Int getMod() const { return mod; }
};

} // namespace nachia

namespace nachia{

template<unsigned int IDENTIFER, class IDENTIFER2 = void>
class DynamicModint{
    using Int = unsigned int;
    using MyType = DynamicModint;
private:
    static DynamicModSupplier _c;
    Int v;
    template< class Elem >
    static Elem SafeMod(Elem x, Int mod){
        if(x < 0){
            if(0 <= x+mod) return x + mod;
            return mod - ((-(x+mod)-1) % mod + 1);
        }
        return x % mod;
    }
public:
    DynamicModint() : v(0) {}
    DynamicModint(const MyType& r) : v(r.v) {}
    MyType& operator=(const MyType&) = default;
    DynamicModint(long long x){ v = SafeMod(x, _c.getMod()); }
    static MyType raw(Int _v){ MyType res; res.v = _v; return res; }
    static void setMod(DynamicModSupplier sup){ _c = std::move(sup); }
    MyType operator+=(MyType r){ return v = _c.add(v, r.v); }
    MyType operator+(MyType r) const { return raw(_c.add(v, r.v)); }
    MyType operator-=(MyType r){ return v = _c.sub(v, r.v); }
    MyType operator-(MyType r) const { return raw(_c.sub(v, r.v)); }
    MyType operator-() const { return raw(v ? _c.getMod()-v : 0); }
    MyType operator*=(MyType r){ return v = _c.mul(v, r.v); }
    MyType operator*(MyType r) const { return raw(_c.mul(v, r.v)); }
    MyType operator/=(MyType r){ return v = _c.mul(v, _c.inv(r.v)); }
    MyType operator/(MyType r) const { return raw(_c.mul(v, _c.inv(r.v))); }
    MyType inv() const { return raw(_c.inv(v)); }
    MyType pow(unsigned long long r) const { return raw(_c.pow(v, r)); }
    MyType mulAdd(MyType mul, MyType add) const { return raw(_c.muladd(v, mul.v, add.v)); }
    Int val() const { return v; }
    Int operator*() const { return v; }
    static Int mod(){ return _c.getMod(); }
};

template<unsigned int IDENTIFER, class IDENTIFER2>
DynamicModSupplier DynamicModint<IDENTIFER, IDENTIFER2>::_c;

} // namespace nachia

void testcase(){
    using Int = nachia::BigintDec;
    using Modint = nachia::DynamicModint<0>;
    i64 N; cin >> N;
    if(N == 1){
        cout << "1/1\n";
        return;
    }
    vector<i64> A;
    for(i64 p=2; p<=N; p++) if(nachia::IsprimeExplicit(p)){
        i64 q = p; while(q*p <= N) q *= p;
        A.push_back(q);
    }
    N = A.size();
    sort(A.begin(), A.end());
    vector<int> X(N,-1), Y(N,-1);
    rep(i,N-1){ X.push_back(i*2); Y.push_back(i*2+1); }
    int n = X.size();
    vector<Int> prod(n);
    rep(i,N) prod[i] = A[i];
    for(int i=N; i<n; i++) prod[i] = prod[X[i]] * prod[Y[i]];
    //for(auto a : prod) cout << a << endl;
    //cout << endl;
    vector<Int> Z(n);
    Z.back() = 1;
    for(int i=n-1; i>=N; i--){
        Z[X[i]] = (Z[i] * prod[Y[i]]).divrem(prod[X[i]]).second;
        Z[Y[i]] = (Z[i] * prod[X[i]]).divrem(prod[Y[i]]).second;
    }
    //rep(i,N) cout << A[i] << " ";
    //cout << endl;
    vector<int> Q(N);
    rep(i,N){
        Modint::setMod(A[i]);
        Q[i] = Modint(stoll(Z[i].toString())).inv().val();
    }
    //rep(i,N) cout << Q[i] << " ";
    //cout << endl;
    using M2 = nachia::StaticModint<998244353>;
    M2 f = 0;
    M2 g = 1;
    rep(i,N){
        auto a = M2(A[i]).inv();
        f += a * M2(Q[i]);
        g *= a;
    }
    int p = (f - g).val();
    //cout << p << endl;
    rep(i,N){
        if(i+p>=N){
            cout << (Q[i] - A[i]);
        } else {
            if(i) cout << "+";
            cout << Q[i];
        }
        cout << "/";
        cout << A[i];
    }

    cout << "\n";
}

int main(){
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int N; cin >> N;
    rep(n,N) testcase();
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3836kb

input:

2
3
6

output:

1/2-1/3
2/3-1/4-2/5

result:

ok OK, t = 2

Test #2:

score: 0
Accepted
time: 0ms
memory: 3508kb

input:

1
1

output:

1/1

result:

ok OK, t = 1

Test #3:

score: 0
Accepted
time: 0ms
memory: 3528kb

input:

10
1
2
3
4
5
6
7
8
9
10

output:

1/1
1/2
1/2-1/3
1/3-1/4
2/3-1/4-2/5
2/3-1/4-2/5
2/3+1/4-1/5-5/7
1/3+2/5+1/7-7/8
4/5+5/7-5/8-8/9
4/5+5/7-5/8-8/9

result:

ok OK, t = 10

Test #4:

score: 0
Accepted
time: 1ms
memory: 3668kb

input:

54
7
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
3
47
81

output:

2/3+1/4-1/5-5/7
3/5+2/7+5/9-2/11-9/13-1/16-5/17-4/19
1/2
1/2-1/3
1/3-1/4
2/3-1/4-2/5
2/3-1/4-2/5
2/3+1/4-1/5-5/7
1/3+2/5+1/7-7/8
4/5+5/7-5/8-8/9
4/5+5/7-5/8-8/9
4/5+3/7+1/8-4/9-10/11
4/5+3/7+1/8-4/9-10/11
3/5+4/7-3/8-1/9-5/11-3/13
3/5+4/7-3/8-1/9-5/11-3/13
3/5+4/7-3/8-1/9-5/11-3/13
4/5+2/7+4/9-8/11-...

result:

ok OK, t = 54

Test #5:

score: 0
Accepted
time: 6ms
memory: 3812kb

input:

92
51
54
57
60
63
66
69
72
75
78
81
84
87
90
93
96
99
102
105
108
111
114
117
120
123
126
129
132
135
138
141
144
147
150
153
156
159
162
165
168
171
174
177
180
183
186
189
192
195
198
201
204
207
210
213
216
219
222
225
228
231
234
237
240
243
246
249
252
255
258
261
264
267
270
273
276
279
282
28...

output:

10/11+2/13+11/17+8/19+19/23+21/25-25/27-5/29-13/31-5/32-16/37-15/41-13/43-26/47-23/49
6/11+2/13+14/17+17/19+6/23+7/25+25/27+1/29-2/31-17/32-1/37-32/41-40/43-20/47-18/49-42/53
6/11+2/13+14/17+17/19+6/23+7/25+25/27+1/29-2/31-17/32-1/37-32/41-40/43-20/47-18/49-42/53
7/11+4/13+6/17+18/19+4/23+23/25+5/27...

result:

ok OK, t = 92

Test #6:

score: 0
Accepted
time: 164ms
memory: 3964kb

input:

1000
622
149
839
472
292
345
799
941
449
15
907
494
48
430
505
66
83
97
10
548
286
644
528
249
573
860
557
932
746
262
971
157
603
715
984
333
53
916
784
649
70
768
780
64
118
616
979
466
24
2
517
774
566
419
182
222
40
169
951
830
977
383
355
770
134
973
917
3
854
31
35
825
109
945
671
536
952
888
...

output:

7/29+21/31+28/37+15/41+25/43+41/47+4/53+18/59+51/61+50/67+18/71+66/73+47/79+77/83+82/89+85/97+90/101+11/103+66/107+76/109+28/113+95/121+2/125+16/127+91/131+34/137+23/139+7/149+129/151+75/157+8/163+20/167+11/169+70/173+138/179+40/181+130/191+120/193+14/197+107/199+102/211+108/223+144/227+128/229+137/...

result:

ok OK, t = 1000

Test #7:

score: 0
Accepted
time: 674ms
memory: 3724kb

input:

1000
1748
1741
1576
1940
1648
1825
1183
1447
1318
1277
1913
1208
1417
1388
1143
1581
1222
1904
1407
1006
1175
1218
1734
1934
1003
1704
1984
1399
1333
1840
1317
1233
1133
1232
1776
1881
1476
1712
1401
1231
1978
1964
1419
1644
1103
1498
1454
1480
1377
1352
1837
1616
1009
1413
1199
1977
1477
1579
1920
...

output:

21/43+23/47+47/53+14/59+19/61+57/67+26/71+14/73+20/79+43/83+65/89+63/97+7/101+60/103+88/107+4/109+107/113+92/127+84/131+20/137+77/139+142/149+64/151+108/157+91/163+104/167+162/169+49/173+20/179+110/181+124/191+110/193+28/197+177/199+10/211+37/223+118/227+88/229+9/233+33/239+62/241+144/251+190/257+11...

result:

ok OK, t = 1000

Test #8:

score: 0
Accepted
time: 1480ms
memory: 4024kb

input:

1000
2107
2115
2985
2832
2564
2529
2971
2637
2666
2172
2496
2191
2465
2199
2260
2161
2402
2369
2762
2674
2734
2252
2488
2185
2652
2014
2018
2960
2313
2063
2696
2976
2457
2247
2180
2647
2907
2901
2912
2538
2512
2623
2267
2986
2348
2170
2131
2166
2563
2111
2860
2254
2462
2080
2054
2803
2397
2778
2411
...

output:

14/47+31/53+57/59+58/61+22/67+54/71+35/73+41/79+33/83+26/89+29/97+43/101+23/103+54/107+55/109+57/113+67/127+58/131+38/137+115/139+5/149+52/151+102/157+97/163+146/167+18/169+124/173+157/179+177/181+93/191+145/193+184/197+125/199+108/211+46/223+27/227+72/229+222/233+104/239+44/241+175/251+229/257+153/...

result:

ok OK, t = 1000

Test #9:

score: -100
Time Limit Exceeded

input:

1000
3416
3784
3793
3610
3982
3174
3253
3088
3197
3926
3664
3669
3431
3821
3340
3298
3498
3627
3194
3354
3362
3512
3865
3529
3988
3973
3852
3552
3672
3282
3035
3639
3998
3090
3771
3618
3402
3139
3903
3110
3452
3947
3941
3225
3187
3283
3243
3722
3808
3491
3309
3935
3937
3259
3909
3665
3809
3390
3285
...

output:

30/59+58/61+10/67+1/71+37/73+10/79+11/83+81/89+37/97+29/101+54/103+20/107+20/109+23/113+21/127+106/131+102/137+43/139+17/149+41/151+22/157+48/163+104/167+30/173+116/179+114/181+113/191+155/193+126/197+90/199+209/211+71/223+15/227+39/229+224/233+168/239+117/241+216/251+202/257+120/263+145/269+15/271+...

result: