QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#819221#998. 素数分解GoatGirl98AC ✓1052ms3792kbC++147.6kb2024-12-18 14:17:442024-12-18 14:17:46

Judging History

This is the latest submission verdict.

  • [2024-12-18 14:17:46]
  • Judged
  • Verdict: AC
  • Time: 1052ms
  • Memory: 3792kb
  • [2024-12-18 14:17:44]
  • Submitted

answer

#include <stdio.h>
#include <assert.h>
#include <vector>
#include <algorithm>
#define getchar getchar_unlocked
#define putchar putchar_unlocked
using namespace std;
using i64 = long long;
using i128 = __int128;
using u64 = unsigned long long;
using u128 = __uint128_t;

u128 rd()
{
    u128 k = 0;
    char c = getchar();
    while (c < '0' || c > '9')
        c = getchar();
    while (c >= '0' && c <= '9')
    {
        k = (k << 1) + (k << 3) + (c ^ 48);
        c = getchar();
    }
    return k;
}

void wr(u128 x)
{
    if (x > 9)
        wr(x / 10);
    putchar(x % 10 + '0');
}

const u128 MSB128 = ((u128)0x8000000000000000ull) << 64;
struct u256
{
    u128 lo, hi;
    u256() {}
    u256(u128 lo, u128 hi) : lo(lo), hi(hi) {}
};
const u256 ten = u256(10, 0);
struct u512
{
    u256 lo, hi;
    u512() {}
    u512(u256 lo, u256 hi) : lo(lo), hi(hi) {}
};

// return a < b ? -1 : a == b ? 0 : 1
int cmp256(u256 a, u256 b)
{
    if (a.hi == b.hi && a.lo == b.lo)
        return 0;
    else if ((a.hi > b.hi) || ((a.hi == b.hi) && (a.lo > b.lo)))
        return 1;
    else
        return -1;
}

void shl256(u256 &a)
{
    a.hi <<= 1;
    a.hi |= ((a.lo & MSB128) ? 1 : 0);
    a.lo <<= 1;
}

void shl512(u512 &a)
{
    shl256(a.hi);
    a.hi.lo |= ((a.lo.hi & MSB128) ? 1 : 0);
    shl256(a.lo);
}

void shr256(u256 &a)
{
    a.lo >>= 1;
    a.lo |= ((a.hi & 1) ? MSB128 : 0);
    a.hi >>= 1;
}

void shr512(u512 &a)
{
    shr256(a.lo);
    a.lo.hi |= ((a.hi.lo & 1) ? MSB128 : 0);
    shr256(a.hi);
}

u256 add256(u256 a, u256 b)
{
    u256 ret;
    ret.hi = a.hi + b.hi;
    ret.lo = a.lo + b.lo;
    if (ret.lo < a.lo || ret.lo < b.lo)
        ++ret.hi;
    return ret;
}

u256 sub256(u256 a, u256 b)
{
    u256 ret;
    ret.hi = a.hi - b.hi;
    ret.lo = a.lo - b.lo;
    if (ret.lo > a.lo)
        --ret.hi;
    return ret;
}

u256 mul128(u128 a, u128 b)
{
    u64 a_hi = a >> 64, a_lo = u64(a);
    u64 b_hi = b >> 64, b_lo = u64(b);
    u128 p01 = u128(a_lo) * b_lo;
    u128 p12 = u128(a_hi) * b_lo + u64(p01 >> 64);
    u64 t_hi = p12 >> 64, t_lo = p12;
    p12 = u128(a_lo) * b_hi + t_lo;
    u128 p23 = u128(a_hi) * b_hi + u64(p12 >> 64) + t_hi;
    return u256(u64(p01) | (p12 << 64), p23);
}

u256 div256(u256 a, u256 b)
{
    u512 p;

    p.hi = u256(0, 0), p.lo = a;
    for (unsigned i = 0; i < 256; ++i)
    {
        shl512(p);
        if (cmp256(p.hi, b) >= 0)
        {
            p.hi = sub256(p.hi, b);
            p.lo.lo |= 1;
        }
    }
    return p.lo;
}

u256 mod256(u256 a, u256 b)
{
    u512 p;

    p.hi = u256(0, 0), p.lo = a;
    for (unsigned i = 0; i < 256; ++i)
    {
        shl512(p);
        if (cmp256(p.hi, b) >= 0)
        {
            p.hi = sub256(p.hi, b);
            p.lo.lo |= 1;
        }
    }
    return p.hi;
}

void print(u256 x)
{
    if (x.hi || (x.lo > 9))
        print(div256(x, ten));
    u256 rem = mod256(x, ten);
    putchar((int)rem.lo + '0');
}

u128 pow_u128(u128 a, u128 t, u128 mod)
{
    u128 r = 1;
    for (; t; t >>= 1, a = mod256(mul128(a, a), u256(mod, 0)).lo)
        if (t & 1)
            r = mod256(mul128(r, a), u256(mod, 0)).lo;
    return r;
}

bool check_prime(u128 n)
{
    static const u128 jp[] = {2, 3, 5, 7, 11, 13, 17, 19};
    if (n == 1 || ((!(n & 1)) && n > 2))
        return false;
    for (u128 p : jp)
        if (n % p == 0)
            return n == p;
    u128 r = n - 1, x, y;
    int e = 0;

    while (~r & 1)
        r >>= 1, ++e;

    for (int p : jp)
    {
        x = pow_u128(p, r, n);

        for (int t = 0; t < e && x > 1; ++t)
        {
            y = mod256(mul128(x, x), u256(n, 0)).lo;

            if (y == 1 && x != n - 1)
                return false;

            x = y;
        }

        if (x != 1)
            return false;
    }

    return true;
}

u128 next_prime(u128 n)
{
    n += ~n & 1;

    while (!check_prime(n += 2))
        ;

    return n;
}

u128 ctz(u128 x) { return (!x) ? 128 : u64(x) ? __builtin_ctzll(x) : __builtin_ctzll(x >> 64) + 64; }

u128 gcd(u128 a, u128 b)
{
    if (!a || !b)
        return a | b;

    int shift = ctz(a | b);

    for (b >>= ctz(b); a; a -= b)
        if ((a >>= ctz(a)) < b)
            swap(a, b);

    return b << shift;
}


namespace rho
{
    // global area for mont(N), N is odd
    // assume that mod is odd
    struct Mont
    {
        u128 mod, inv, r2;
        Mont(u128 n) : mod(n)
        {
            assert(n & 1);
            inv = n;

            for (int i = 0; i < 6; ++i)
                inv *= (2 - n * inv);

            r2 = (~n + 1) % n;

            for (int i = 0; i < 4; ++i)
                if ((r2 <<= 1) >= mod)
                    r2 -= mod;

            for (int i = 0; i < 5; ++i)
                r2 = mul(r2, r2);
        }
        u128 reduce(u256 x) const
        {
            u128 y = x.hi - mul128(x.lo * inv, mod).hi;
            return (y & MSB128) ? y + mod : y;
        }
        u128 reduce(u128 x) const { return reduce(u256(x, 0)); }
        u128 init(u128 n) const { return reduce(mul128(n, r2)); }
        u128 mul(u128 a, u128 b) const { return reduce(mul128(a, b)); }
    } mont(1);
    u128 N;
    u128 add(u128 a, u128 b) { return (a < N - b) ? a + b : sub256(add256(u256(a, 0), u256(b, 0)), u256(N, 0)).lo; }
    u128 sub(u128 a, u128 b) { return (a < b) ? sub256(add256(u256(a, 0), u256(N, 0)), u256(b, 0)).lo : a - b; }
    u128 mul(u128 a, u128 b) { return mont.mul(a, b); }

    vector<u128> ans;
    u128 rho(u128 n, int c, int S)
    {
        if (n % 2 == 0)
            return 2;

        u128 x = 2, y = 2, d;

        for (;;)
        {
            u128 a = x, b = y;
            d = 1;

            for (int i = 0; i < S; ++i)
            {
                x = add(mul(x, x), c);
                y = add(mul(y, y), c);
                y = add(mul(y, y), c);
                d = mul(d, sub(x, y));
            }

            d = gcd(d, n);

            if (d == 1)
                continue;

            if (d != n)
                return d;

            x = a, y = b;

            for (int i = 0; i < S; ++i)
            {
                x = add(mul(x, x), c);
                y = add(mul(y, y), c);
                y = add(mul(y, y), c);
                d = gcd(n, sub(x, y));

                if (d != 1)
                    return d % n;
            }

            return 0;
        }
    }

    u128 pollard_brent_montgomery(u128 n)
    {
        u128 res = rho(n, 1, 128), c = 2;
        for (; !res; c++)
            res = rho(n, c, 128);
        return res;
    }

    void doit(u128 n)
    {
        N = n, mont = Mont(N);

        if (check_prime(n))
            ans.push_back(n);
        else
        {
            u128 res = pollard_brent_montgomery(n);
            doit(res), doit(n / res);
        }
    }
    vector<u128> solve(u128 n)
    {
        ans.clear();
        // special optimize for even (or the Mont optimization is unavailable)
        while (!(n & 1))
            ans.push_back(2), n >>= 1;
        if (n <= 1)
            return ans;
        doit(n);
        sort(ans.begin(), ans.end());
        return ans;
    }
}

int main()
{
    u128 T = 1;
    while (T--)
    {
        u128 n = rd();
        vector<u128> ans = rho::solve(n);
        // wr(ans.size()), putchar(' ');
        for (size_t i = 0; i < ans.size(); ++i)
            wr(ans[i]), putchar(' ');
        putchar('\n');
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3736kb

input:

9866369

output:

113 87313 

result:

ok single line: '113 87313 '

Test #2:

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

input:

9676411

output:

617 15683 

result:

ok single line: '617 15683 '

Test #3:

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

input:

9717809

output:

727 13367 

result:

ok single line: '727 13367 '

Test #4:

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

input:

9957119

output:

829 12011 

result:

ok single line: '829 12011 '

Test #5:

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

input:

9868337

output:

983 10039 

result:

ok single line: '983 10039 '

Test #6:

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

input:

9561023

output:

1163 8221 

result:

ok single line: '1163 8221 '

Test #7:

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

input:

9545761

output:

1367 6983 

result:

ok single line: '1367 6983 '

Test #8:

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

input:

9607667

output:

1621 5927 

result:

ok single line: '1621 5927 '

Test #9:

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

input:

9597001

output:

2161 4441 

result:

ok single line: '2161 4441 '

Test #10:

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

input:

9761267

output:

3023 3229 

result:

ok single line: '3023 3229 '

Test #11:

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

input:

982258310053

output:

3947 248861999 

result:

ok single line: '3947 248861999 '

Test #12:

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

input:

951649112653

output:

60727 15670939 

result:

ok single line: '60727 15670939 '

Test #13:

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

input:

970510479737

output:

82361 11783617 

result:

ok single line: '82361 11783617 '

Test #14:

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

input:

986989368881

output:

104347 9458723 

result:

ok single line: '104347 9458723 '

Test #15:

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

input:

957993963593

output:

137957 6944149 

result:

ok single line: '137957 6944149 '

Test #16:

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

input:

994965772309

output:

189859 5240551 

result:

ok single line: '189859 5240551 '

Test #17:

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

input:

978534040373

output:

243157 4024289 

result:

ok single line: '243157 4024289 '

Test #18:

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

input:

971024997479

output:

316531 3067709 

result:

ok single line: '316531 3067709 '

Test #19:

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

input:

953600891731

output:

550909 1730959 

result:

ok single line: '550909 1730959 '

Test #20:

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

input:

957601483897

output:

974189 982973 

result:

ok single line: '974189 982973 '

Test #21:

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

input:

977141658538805467

output:

245593 3978703214419 

result:

ok single line: '245593 3978703214419 '

Test #22:

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

input:

993640296811069513

output:

15772423 62998582831 

result:

ok single line: '15772423 62998582831 '

Test #23:

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

input:

972033526800786343

output:

22838183 42561771521 

result:

ok single line: '22838183 42561771521 '

Test #24:

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

input:

954171962745034819

output:

35159623 27138287653 

result:

ok single line: '35159623 27138287653 '

Test #25:

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

input:

978341504612724647

output:

52896463 18495404969 

result:

ok single line: '52896463 18495404969 '

Test #26:

score: 0
Accepted
time: 2ms
memory: 3444kb

input:

964156325695679951

output:

82257599 11721182449 

result:

ok single line: '82257599 11721182449 '

Test #27:

score: 0
Accepted
time: 2ms
memory: 3512kb

input:

981810768141725077

output:

120632453 8138861009 

result:

ok single line: '120632453 8138861009 '

Test #28:

score: 0
Accepted
time: 2ms
memory: 3792kb

input:

996600025433706263

output:

188473367 5287749889 

result:

ok single line: '188473367 5287749889 '

Test #29:

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

input:

953178770133147331

output:

434148317 2195514143 

result:

ok single line: '434148317 2195514143 '

Test #30:

score: 0
Accepted
time: 2ms
memory: 3604kb

input:

979704186959920183

output:

965382697 1014835039 

result:

ok single line: '965382697 1014835039 '

Test #31:

score: 0
Accepted
time: 2ms
memory: 3564kb

input:

9681177706327259719477027

output:

30892241 313385413066253747 

result:

ok single line: '30892241 313385413066253747 '

Test #32:

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

input:

9940536208068119834895493

output:

9801019853 1014234881385881 

result:

ok single line: '9801019853 1014234881385881 '

Test #33:

score: 0
Accepted
time: 3ms
memory: 3464kb

input:

9997038881982298860346319

output:

17471050273 572205947883503 

result:

ok single line: '17471050273 572205947883503 '

Test #34:

score: 0
Accepted
time: 9ms
memory: 3420kb

input:

9756859113937123210682929

output:

30453215099 320388473999171 

result:

ok single line: '30453215099 320388473999171 '

Test #35:

score: 0
Accepted
time: 18ms
memory: 3516kb

input:

9990078255400923282753323

output:

54825911561 182214540004243 

result:

ok single line: '54825911561 182214540004243 '

Test #36:

score: 0
Accepted
time: 34ms
memory: 3516kb

input:

9883626478214751636971843

output:

99236894717 99596289327679 

result:

ok single line: '99236894717 99596289327679 '

Test #37:

score: 0
Accepted
time: 38ms
memory: 3716kb

input:

9573361345198621696137959

output:

174744513737 54784903631407 

result:

ok single line: '174744513737 54784903631407 '

Test #38:

score: 0
Accepted
time: 13ms
memory: 3608kb

input:

9625069927040072137408201

output:

315510198349 30506367075949 

result:

ok single line: '315510198349 30506367075949 '

Test #39:

score: 0
Accepted
time: 51ms
memory: 3732kb

input:

9558955213557944940797347

output:

961448896637 9942239516831 

result:

ok single line: '961448896637 9942239516831 '

Test #40:

score: 0
Accepted
time: 55ms
memory: 3536kb

input:

9840941836621191397321379

output:

3053341569527 3223007191477 

result:

ok single line: '3053341569527 3223007191477 '

Test #41:

score: 0
Accepted
time: 3ms
memory: 3480kb

input:

961656201462920497194293996611

output:

973825889 987503220365627902499 

result:

ok single line: '973825889 987503220365627902499 '

Test #42:

score: 0
Accepted
time: 63ms
memory: 3756kb

input:

996526819694097128105196470881

output:

994411349447 1002127359314908823 

result:

ok single line: '994411349447 1002127359314908823 '

Test #43:

score: 0
Accepted
time: 68ms
memory: 3720kb

input:

984638359916649895753226868473

output:

1913886315953 514470661976784841 

result:

ok single line: '1913886315953 514470661976784841 '

Test #44:

score: 0
Accepted
time: 68ms
memory: 3524kb

input:

954594052218344282851704873817

output:

3979498549097 239877974684763761 

result:

ok single line: '3979498549097 239877974684763761 '

Test #45:

score: 0
Accepted
time: 114ms
memory: 3564kb

input:

951130323482838313925006521277

output:

7557378146273 125854536464064349 

result:

ok single line: '7557378146273 125854536464064349 '

Test #46:

score: 0
Accepted
time: 113ms
memory: 3536kb

input:

962697697567853678189739826037

output:

15100422367399 63753031150060163 

result:

ok single line: '15100422367399 63753031150060163 '

Test #47:

score: 0
Accepted
time: 412ms
memory: 3792kb

input:

956492846963172046572961978627

output:

30582959699219 31275352561367633 

result:

ok single line: '30582959699219 31275352561367633 '

Test #48:

score: 0
Accepted
time: 412ms
memory: 3588kb

input:

990250331253981534128026179673

output:

61400770095961 16127653280347393 

result:

ok single line: '61400770095961 16127653280347393 '

Test #49:

score: 0
Accepted
time: 235ms
memory: 3792kb

input:

963782379204510691122291047909

output:

244564652505673 3940808163935933 

result:

ok single line: '244564652505673 3940808163935933 '

Test #50:

score: 0
Accepted
time: 1052ms
memory: 3756kb

input:

955342769363561101863533963531

output:

973806882626147 981039245468473 

result:

ok single line: '973806882626147 981039245468473 '