結果

問題 No.981 一般冪乗根
ユーザー toyuzuko
提出日時 2022-04-12 23:33:23
言語 PyPy3
(7.3.15)
結果
MLE  
(最新)
AC  
(最初)
実行時間 -
コード長 7,495 bytes
コンパイル時間 142 ms
コンパイル使用メモリ 82,396 KB
実行使用メモリ 1,014,284 KB
最終ジャッジ日時 2024-12-21 10:41:57
合計ジャッジ時間 161,006 ms
ジャッジサーバーID
(参考情報)
judge3 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 27 TLE * 10 MLE * 7
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

from random import randint
from collections import Counter
class Prime():
def __init__(self, m=10**6):
self.m = m
self.isprime = [True] * (m + 1)
self.minfac = [-1] * (m + 1)
self.mobius = [1] * (m + 1)
self.isprime[0] = self.isprime[1] = False
self.minfac[1] = 1
for p in range(2, m + 1):
if not self.isprime[p]: continue
self.minfac[p] = p
self.mobius[p] = -1
for q in range(2 * p, m + 1, p):
self.isprime[q] = False
if self.minfac[q] == -1:
self.minfac[q] = p
if (q // p) % p:
self.mobius[q] *= -1
else:
self.mobius[q] = 0
def gcd(self, x, y):
while y:
x, y = y, x % y
return x
def lcm(self, x, y):
return x // self.gcd(x, y) * y
def is_prime(self, n):
if n <= self.m:
return self.isprime[n]
if not n & 1:
return False
return self.miller_rabin(n)
def miller_rabin(self, n):
if n <= 4294967295:
p = [2, 7, 61]
elif n <= 281474976710655:
p = [2, 3, 5, 7, 11, 13, 17]
elif n <= 18446744073709551615:
p = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
else:
p = [randint(1, n - 1) for _ in range(20)]
d = n - 1
d = d // (d & -d)
for a in p:
t = d
y = pow(a, t, n)
if y == 1: continue
while y != n - 1:
y = (y * y) % n
if y == 1 or t == n - 1: return False
t <<= 1
return True
def factorize(self, n):
if n <= self.m:
return self.factorize_fast(n)
if self.is_prime(n):
return [n]
res = []
stack = [n]
while stack:
tmp = stack.pop()
if tmp <= self.m:
res.extend(self.factorize_fast(tmp))
continue
p = self.pollard_rho(tmp)
q = tmp // p
pri_p = self.is_prime(p)
pri_q = self.is_prime(q)
if pri_p and pri_q:
res.append(p)
res.append(q)
elif pri_p:
res.append(p)
while not q % p:
res.append(p)
q //= p
if self.is_prime(q):
res.append(q)
else:
stack.append(q)
elif pri_q:
res.append(q)
while not p % q:
res.append(q)
p //= q
if self.is_prime(p):
res.append(p)
else:
stack.append(p)
else:
stack.append(p)
stack.append(q)
return sorted(res)
def factorize_fast(self, n):
res = []
while n > 1:
p = self.minfac[n]
while self.minfac[n] == p:
n //= p
res.append(p)
return sorted(res)
def factorize_naive(self, n):
res = []
x, y = n, 2
while y * y <= x:
while not x % y:
res.append(y)
x //= y
y += 1
if x > 1:
res.append(x)
return sorted(res)
def pollard_rho(self, n):
m = int(n**0.125) + 1
s = randint(1, 1000)
while True:
y, r, q = 2, 1, 1
d = 1
while d == 1:
x = y
for _ in range(r):
y = (y * y + s) % n
for k in range(0, r, m):
ys = y
for i in range(min(m, r - k)):
y = (y * y + s) % n
q = q * abs(x - y) % n
d = self.gcd(n, q)
if d != 1:
break
r <<= 1
if d == n:
while d == 1:
ys = (ys * ys + s) % n
d = self.gcd(n, abs(x - ys))
if d != n:
break
s += 1
return d
def divisors(self, n):
if n <= self.m:
return self.divisors_fast(n)
if self.is_prime(n):
return [1, n]
return self.divisors_naive(n)
def divisors_fast(self, n):
res = [1]
f = Counter(self.factorize_fast(n))
for p, d in f.items():
s = len(res)
for i in range(s):
v = 1
for j in range(d):
v *= p
res.append(res[i] * v)
return sorted(res)
def divisors_naive(self, n):
res = []
x, y = n, 1
while y * y < x:
if not x % y:
res.append(y)
res.append(x // y)
y += 1
if y * y == x:
res.append(y)
return sorted(res)
def zeta_transform(self, arr):
n = len(arr)
assert n <= self.m
res = arr.copy()
for p in range(2, n):
if not self.isprime[p]:
continue
for k in range(1, (n - 1) // p + 1)[::-1]:
res[k] += res[k * p]
return res
def mobius_transform(self, arr):
n = len(arr)
assert n <= self.m
res = arr.copy()
for p in range(2, n):
if not self.isprime[p]:
continue
for k in range(p, n, p):
res[k // p] -= res[k]
return res
def convolution_gcd(self, f, g):
assert len(f) == len(g)
F = self.zeta_transform(f)
G = self.zeta_transform(g)
H = [u * v for u, v in zip(F, G)]
h = self.mobius_transform(H)
return h
P = Prime(1)
from math import gcd, sqrt
def primitive_root(m):
if m == 2: return 1
divs = set(P.factorize_naive(m - 1))
g = 2
while True:
for d in divs:
if pow(g, (m - 1) // d, m) == 1: break
else:
return g
g += 1
def discrete_logarithm(x, y, m):
if m == 1: return 0
if y == 1: return 0
if x == y == 0: return 1
sq = int(sqrt(m)) + 1
powx = {}
p = 1
for i in range(sq + 1):
if p % m == y: return i
powx[p * y % m] = i
p *= x
p %= m
z = pow(x, sq, m)
g = z
for i in range(1, sq + 1):
if g in powx:
res = i * sq - powx[g]
if pow(x, res, m) == y: return res
g *= z
g %= m
return -1
def inv_gcd(a, b):
a %= b
if a == 0: return b, 0
s, t, m0, m1 = b, a, 0, 1
while t:
u = s // t
s -= t * u
m0 -= m1 * u
s, t = t, s
m0, m1 = m1, m0
if m0 < 0: m0 += b // s
return s, m0
def inv_mod(x, m):
g, im = inv_gcd(x, m)
return im
def kth_root(k, y, p):
if k == 0:
if y == 1:
return 0
else:
return -1
if y == 0:
return 0
g = gcd(k, p - 1)
m = (p - 1) // g
if pow(a, m, p) != 1: return -1
r = primitive_root(p)
l = discrete_logarithm(r, y, p)
if l % g: return -1
res = pow(r, l // g * inv_mod(k // g, m) % m, p)
return res
T = int(input())
for _ in range(T):
p, k, a = map(int, input().split())
print(kth_root(k, a, p))
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0