結果

問題 No.2066 Simple Math !
ユーザー chineristACchineristAC
提出日時 2022-09-02 22:15:02
言語 PyPy3
(7.3.15)
結果
WA  
実行時間 -
コード長 3,754 bytes
コンパイル時間 182 ms
コンパイル使用メモリ 81,908 KB
実行使用メモリ 79,348 KB
最終ジャッジ日時 2024-04-27 21:49:46
合計ジャッジ時間 4,376 ms
ジャッジサーバーID
(参考情報)
judge1 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 44 ms
63,916 KB
testcase_01 AC 136 ms
77,656 KB
testcase_02 AC 285 ms
79,348 KB
testcase_03 WA -
testcase_04 TLE -
testcase_05 -- -
testcase_06 -- -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
testcase_23 -- -
testcase_24 -- -
testcase_25 -- -
testcase_26 -- -
testcase_27 -- -
testcase_28 -- -
testcase_29 -- -
testcase_30 -- -
testcase_31 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys,random,bisect
from collections import deque,defaultdict,Counter
from heapq import heapify,heappop,heappush
from itertools import cycle, permutations
from math import log,gcd

input = lambda :sys.stdin.readline().rstrip()
mi = lambda :map(int,input().split())
li = lambda :list(mi())

def floor_sum(n: int, m: int, a: int, b: int) -> int:
    ans = 0

    if a >= m:
        ans += (n - 1) * n * (a // m) // 2
        a %= m

    if b >= m:
        ans += n * (b // m)
        b %= m

    y_max = (a * n + b) // m
    x_max = y_max * m - b

    if y_max == 0:
        return ans

    ans += (n - (x_max + a - 1) // a) * y_max
    ans += floor_sum(y_max, a, m, (a - x_max % a) % a)

    return ans

def _inv_gcd(a,b):
    a %= b
    if a == 0:
        return (b, 0)
 
    # Contracts:
    # [1] s - m0 * a = 0 (mod b)
    # [2] t - m1 * a = 0 (mod b)
    # [3] s * |m1| + t * |m0| <= b
    s = b
    t = a
    m0 = 0
    m1 = 1
 
    while t:
        u = s // t
        s -= t * u
        m0 -= m1 * u  # |m1 * u| <= |m1| * s <= b
 
        # [3]:
        # (s - t * u) * |m1| + t * |m0 - m1 * u|
        # <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)
        # = s * |m1| + t * |m0| <= b
 
        s, t = t, s
        m0, m1 = m1, m0
 
    # by [3]: |m0| <= b/g
    # by g != b: |m0| < b/g
    if m0 < 0:
        m0 += b // s
 
    return (s, m0)
 
def crt(r,m):
    assert len(r) == len(m)
 
    n = len(r)
 
    # Contracts: 0 <= r0 < m0
    r0 = 0
    m0 = 1
    for i in range(n):
        assert 1 <= m[i]
        r1 = r[i] % m[i]
        m1 = m[i]
        if m0 < m1:
            r0, r1 = r1, r0
            m0, m1 = m1, m0
        if m0 % m1 == 0:
            if r0 % m1 != r1:
                return (0, 0)
            continue
 
        # assume: m0 > m1, lcm(m0, m1) >= 2 * max(m0, m1)
 
        '''
        (r0, m0), (r1, m1) -> (r2, m2 = lcm(m0, m1));
        r2 % m0 = r0
        r2 % m1 = r1
        -> (r0 + x*m0) % m1 = r1
        -> x*u0*g % (u1*g) = (r1 - r0) (u0*g = m0, u1*g = m1)
        -> x = (r1 - r0) / g * inv(u0) (mod u1)
        '''
 
        # im = inv(u0) (mod u1) (0 <= im < u1)
        g, im = _inv_gcd(m0, m1)
 
        u1 = m1 // g
        # |r1 - r0| < (m0 + m1) <= lcm(m0, m1)
        if (r1 - r0) % g:
            return (0, 0)
 
        # u1 * u1 <= m1 * m1 / g / g <= m0 * m1 / g = lcm(m0, m1)
        x = (r1 - r0) // g % u1 * im % u1
 
        '''
        |r0| + |m0 * x|
        < m0 + m0 * (u1 - 1)
        = m0 + m0 * m1 / g - m0
        = lcm(m0, m1)
        '''
 
        r0 += x * m0
        m0 *= u1  # -> lcm(m0, m1)
        if r0 < 0:
            r0 += m0
 
    return (r0, m0)

def calc(P,Q,K):
    g = gcd(P,Q)
    p,q = P//g,Q//g

    r0,m0 = crt([1,0],[p,q])
    x0,y0 = (1-r0)//p,r0//q
    assert p*x0 + q*y0 == 1
    assert 0 <= y0

    #print((x0,y0))

    if 0 <= x0:
        return K
    
    x0 *= -1



    PQ_less = floor_sum(p*q-1,p,y0,y0) - floor_sum(p*q-1,q,x0,x0-1)

    def cnt(m):
        if m < p*q:
            return floor_sum(m,p,y0,y0) - floor_sum(m,q,x0,x0-1)
        else:
            return PQ_less + m-p*q+1
    
    
    ok = 10**18
    ng = 0
    while ok-ng>1:
        mid = (ok+ng)//2
        if cnt(mid) >= K:
            ok = mid
        else:
            ng = mid
    
    res = ok

    res *= g

    return res

def brute(P,Q,K):
    g = gcd(P,Q)
    P,Q = P//g,Q//g
    res = []
    for i in range(Q):
        for j in range(P):
            if (i,j)!=(0,0) and P*i+Q*j < P*Q:
                res.append(P*i+Q*j)
    res = sorted(set(res))

    if len(res) >= K:
        return res[K-1] * g
    else:
        return (P*Q + K - len(res) - 1) * g
    




for _ in range(int(input())):
    P,Q,K = mi()
    print(calc(P,Q,K))
    #print(brute(P,Q,K))

    
0