結果
問題 | No.981 一般冪乗根 |
ユーザー |
![]() |
提出日時 | 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 |
ソースコード
from random import randintfrom collections import Counterclass Prime():def __init__(self, m=10**6):self.m = mself.isprime = [True] * (m + 1)self.minfac = [-1] * (m + 1)self.mobius = [1] * (m + 1)self.isprime[0] = self.isprime[1] = Falseself.minfac[1] = 1for p in range(2, m + 1):if not self.isprime[p]: continueself.minfac[p] = pself.mobius[p] = -1for q in range(2 * p, m + 1, p):self.isprime[q] = Falseif self.minfac[q] == -1:self.minfac[q] = pif (q // p) % p:self.mobius[q] *= -1else:self.mobius[q] = 0def gcd(self, x, y):while y:x, y = y, x % yreturn xdef lcm(self, x, y):return x // self.gcd(x, y) * ydef is_prime(self, n):if n <= self.m:return self.isprime[n]if not n & 1:return Falsereturn 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 - 1d = d // (d & -d)for a in p:t = dy = pow(a, t, n)if y == 1: continuewhile y != n - 1:y = (y * y) % nif y == 1 or t == n - 1: return Falset <<= 1return Truedef 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))continuep = self.pollard_rho(tmp)q = tmp // ppri_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 //= pif 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 //= qif 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 //= pres.append(p)return sorted(res)def factorize_naive(self, n):res = []x, y = n, 2while y * y <= x:while not x % y:res.append(y)x //= yy += 1if x > 1:res.append(x)return sorted(res)def pollard_rho(self, n):m = int(n**0.125) + 1s = randint(1, 1000)while True:y, r, q = 2, 1, 1d = 1while d == 1:x = yfor _ in range(r):y = (y * y + s) % nfor k in range(0, r, m):ys = yfor i in range(min(m, r - k)):y = (y * y + s) % nq = q * abs(x - y) % nd = self.gcd(n, q)if d != 1:breakr <<= 1if d == n:while d == 1:ys = (ys * ys + s) % nd = self.gcd(n, abs(x - ys))if d != n:breaks += 1return ddef 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 = 1for j in range(d):v *= pres.append(res[i] * v)return sorted(res)def divisors_naive(self, n):res = []x, y = n, 1while y * y < x:if not x % y:res.append(y)res.append(x // y)y += 1if y * y == x:res.append(y)return sorted(res)def zeta_transform(self, arr):n = len(arr)assert n <= self.mres = arr.copy()for p in range(2, n):if not self.isprime[p]:continuefor k in range(1, (n - 1) // p + 1)[::-1]:res[k] += res[k * p]return resdef mobius_transform(self, arr):n = len(arr)assert n <= self.mres = arr.copy()for p in range(2, n):if not self.isprime[p]:continuefor k in range(p, n, p):res[k // p] -= res[k]return resdef 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 hP = Prime(1)from math import gcd, sqrtdef primitive_root(m):if m == 2: return 1divs = set(P.factorize_naive(m - 1))g = 2while True:for d in divs:if pow(g, (m - 1) // d, m) == 1: breakelse:return gg += 1def discrete_logarithm(x, y, m):if m == 1: return 0if y == 1: return 0if x == y == 0: return 1sq = int(sqrt(m)) + 1powx = {}p = 1for i in range(sq + 1):if p % m == y: return ipowx[p * y % m] = ip *= xp %= mz = pow(x, sq, m)g = zfor i in range(1, sq + 1):if g in powx:res = i * sq - powx[g]if pow(x, res, m) == y: return resg *= zg %= mreturn -1def inv_gcd(a, b):a %= bif a == 0: return b, 0s, t, m0, m1 = b, a, 0, 1while t:u = s // ts -= t * um0 -= m1 * us, t = t, sm0, m1 = m1, m0if m0 < 0: m0 += b // sreturn s, m0def inv_mod(x, m):g, im = inv_gcd(x, m)return imdef kth_root(k, y, p):if k == 0:if y == 1:return 0else:return -1if y == 0:return 0g = gcd(k, p - 1)m = (p - 1) // gif pow(a, m, p) != 1: return -1r = primitive_root(p)l = discrete_logarithm(r, y, p)if l % g: return -1res = pow(r, l // g * inv_mod(k // g, m) % m, p)return resT = int(input())for _ in range(T):p, k, a = map(int, input().split())print(kth_root(k, a, p))