結果

問題 No.981 一般冪乗根
ユーザー Kiri8128Kiri8128
提出日時 2020-02-09 01:01:42
言語 PyPy3
(7.3.15)
結果
MLE  
(最新)
AC  
(最初)
実行時間 -
コード長 3,478 bytes
コンパイル時間 300 ms
コンパイル使用メモリ 82,200 KB
実行使用メモリ 551,044 KB
最終ジャッジ日時 2024-10-09 21:04:21
合計ジャッジ時間 184,544 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 4,249 ms
259,156 KB
testcase_01 AC 4,243 ms
262,588 KB
testcase_02 AC 4,193 ms
261,908 KB
testcase_03 AC 4,202 ms
275,292 KB
testcase_04 AC 4,186 ms
256,756 KB
testcase_05 AC 238 ms
136,680 KB
testcase_06 AC 240 ms
83,452 KB
testcase_07 AC 248 ms
83,732 KB
testcase_08 MLE -
testcase_09 AC 242 ms
153,116 KB
testcase_10 AC 240 ms
83,800 KB
testcase_11 AC 240 ms
137,020 KB
testcase_12 AC 245 ms
151,928 KB
testcase_13 AC 246 ms
149,696 KB
testcase_14 AC 238 ms
83,900 KB
testcase_15 AC 245 ms
76,876 KB
testcase_16 AC 239 ms
76,820 KB
testcase_17 AC 239 ms
76,848 KB
testcase_18 AC 246 ms
76,700 KB
testcase_19 AC 247 ms
76,804 KB
testcase_20 AC 237 ms
76,840 KB
testcase_21 AC 238 ms
76,972 KB
testcase_22 AC 238 ms
76,900 KB
testcase_23 AC 236 ms
76,828 KB
testcase_24 AC 240 ms
76,840 KB
testcase_25 AC 4,109 ms
195,588 KB
testcase_26 AC 4,694 ms
214,476 KB
testcase_27 AC 105 ms
76,412 KB
testcase_28 AC 3,907 ms
194,256 KB
evil_60bit1.txt TLE -
evil_60bit2.txt TLE -
evil_60bit3.txt TLE -
evil_hack AC 47 ms
60,760 KB
evil_hard_random TLE -
evil_hard_safeprime.txt TLE -
evil_hard_tonelli0 TLE -
evil_hard_tonelli1 TLE -
evil_hard_tonelli2 TLE -
evil_hard_tonelli3 TLE -
evil_sefeprime1.txt TLE -
evil_sefeprime2.txt TLE -
evil_sefeprime3.txt TLE -
evil_tonelli1.txt TLE -
evil_tonelli2.txt TLE -
権限があれば一括ダウンロードができます

ソースコード

diff #

def primeFactor(N):
    i = 2
    ret = {}
    n = N
    mrFlg = 0
    while i*i <= n:
        k = 0
        while n % i == 0:
            n //= i
            k += 1
        if k: ret[i] = k
        i += 1 + i%2
        if i == 101 and n >= 2**20:
            def findFactorRho(N):
                def gcd(a, b):
                    while b: a, b = b, a % b
                    return a
                def f(x, c):
                    return (x * x + c) % N
                for c in range(1, 99):
                    X, d, j = [2], 1, 0
                    while d == 1:
                        j += 1
                        X.append(f(X[-1], c))
                        X.append(f(X[-1], c))
                        d = gcd(abs(X[2*j]-X[j]), N)
                    if d != N:
                        if isPrimeMR(d):
                            return d
                        elif isPrimeMR(N//d): return N//d
            while n > 1:
                if isPrimeMR(n):
                    ret[n], n = 1, 1
                else:
                    mrFlg = 1
                    j = findFactorRho(n)
                    k = 0
                    while n % j == 0:
                        n //= j
                        k += 1
                    ret[j] = k

    if n > 1: ret[n] = 1
    if mrFlg > 0: ret = {x: ret[x] for x in sorted(ret)}
    return ret

def isPrimeMR(n):
    if n == 2:
        return True
    if n == 1 or n & 1 == 0:
        return False
    d = (n - 1) >> 1
    while d & 1 == 0:
        d >>= 1
    
    L = [2, 7, 61] if n < 1<<32 else [2, 13, 23, 1662803] if n < 1<<40 else [2, 3, 5, 7, 11, 13, 17] if n < 1<<48 else [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
    for a in L:
        t = d
        y = pow(a, t, n)
        while t != n - 1 and y != 1 and y != n - 1:
            y = (y * y) % n
            t <<= 1

        if y != n - 1 and t & 1 == 0:
            return False
    return True

def discrete_logarithm(a, b, mod):
    a %= mod
    b %= mod
    m = int(mod**0.5+0.9) + 1
    s = 1
    for i in range(m):
        if s == b:
            return i
        s = s * a % mod
        
    inva = pow(a, mod-2, mod)
    am = pow(a, m, mod)
    D = {}
    k = b
    for i in range(m):
        if k not in D:
            D[k] = i
        k = k * inva % mod
    k = 1
    for i in range(m):
        if k in D:
            return D[k] + i * m
        k = k * am % mod
    return -1

def primitive_root(mod, pf):
    for i in range(1, mod):
        for q in pf:
            if pow(i, (mod-1) // q, mod) == 1:
                break
        else:
            return i

def gcd(a, b):
    while b: a, b = b, a % b
    return abs(a)

def inv(x, nn):
    def invv(a, n):
        if a == 1: return (1, 0)
        if a == 0: return (-1, -1)
        b, m = a, n
        while m != 0: b,m = m,b%m
        if b > 1: return (-1, -1)
        k = n // a
        y, yy = invv(n % a, a)
        if y < 0: return (-1, -1)
        x = yy - k * y
        while x < 0:
            x += n
            y -= a
        return (x, y)
    return invv(x, nn)[0]

T = int(input())
for _ in range(T):
    p, k, a = map(int, input().split())
    pp = p-1
    pf = primeFactor(pp)
    h = primitive_root(p, pf)
    b = discrete_logarithm(h, a, p)
    while True:
        g = gcd(k, pp)
        if g == 1: break
        if b % g:
            print(-1)
            break
        b //= g
        k //= g
        pp //= g
    if g > 1: continue
    print(pow(h, b * inv(k, pp) % pp, p))
0