QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#819221 | #998. 素数分解 | GoatGirl98 | AC ✓ | 1052ms | 3792kb | C++14 | 7.6kb | 2024-12-18 14:17:44 | 2024-12-18 14:17:46 |
Judging History
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 '