Каосар і НСД#12273

Каосар і НСД (Розбір)

Автор проблеми:

AlKaosar Hussain

Підготовлено:

Hasan Saleh (MathModel)

Редагував:

Hasan Saleh (MathModel)

Рішення Ми беремо числа

\binom{n}{1}, \binom{n}{2}, \dots, \binom{n}{m}

і хочемо

\gcd\bigl(\binom{n}{1},\binom{n}{2},\dots,\binom{n}{m}\bigr).

Чистий спосіб зробити це - подивитися на це простими числами. Нехай

n = \prod_{p} p^{e_p}

буде простим розкладом . НСД біноміальних коефіцієнтів також буде дільником , отже, він матиме форму

\prod_{p \mid n} p^{f_p}

для деяких f_p \le e_p. Наша задача - знайти для кожного простого числа , яке ділить , яка найменша степінь , що з'являється в усіх

\binom{n}{1}, \binom{n}{2}, \dots, \binom{n}{m}.

Ця "найменша степінь" є точною

f_p = e_p - \bigl\lfloor \log_p m \bigr\rfloor,

але ніколи не від'ємною (якщо вона стає від'ємною, ми просто ставимо ).

Чому це правда? Фіксуємо просте число і припустимо, що має -адичну оцінку , тобто n = p^e \cdot r з \gcd(r,p)=1. Тепер подивіться на біноміальний коефіцієнт з k = p^t, де

t = \bigl\lfloor \log_p m \bigr\rfloor \quad\text{так що}\quad p^t \le m < p^{t+1}.

Цей знаходиться в нашому діапазоні 1 \le k \le m. Для цього спеціального можна перевірити (це стандартний факт і може бути доведено з перенесеннями в основі або шляхом розгляду факторіалів), що

v_p\bigl(\binom{n}{p^t}\bigr) = e - t.

Отже, для цього конкретного степінь всередині \binom{n}{k} є точною p^{e-t}. Це вже показує, що НСД не може мати більше, ніж p^{e-t}.

Друга частина полягає в тому, що для будь-якого k \le m ви не можете отримати меншу степінь , ніж e - t. Інтуїтивно: щоб "вбити" більше степенів в біноміальному коефіцієнті, повинен містити більше факторів в , але до ви можете отримати максимум \lfloor \log_p m \rfloor факторів з знаменника, тому показник у біноміальному коефіцієнті залишається \ge e - \lfloor \log_p m \rfloor. Отже, мінімум для всіх k \in [1,m] є точно

\min_{1 \le k \le m} v_p\bigl(\binom{n}{k}\bigr) = e - \bigl\lfloor \log_p m \bigr\rfloor \quad (\text{але не нижче }0).

Збираючи це разом для всіх простих чисел, що ділять , ми отримуємо

\gcd_{1 \le k \le m} \binom{n}{k} = \prod_{p^e \parallel n} p^{\max\{0,\, e - \lfloor \log_p m \rfloor\}}.

Код робить саме це:

  • розкладає на прості числа з показниками ;

  • для кожного обчислює \texttt{flog}(m,p), що буквально є

    \texttt{flog}(m,p) = \left\lfloor \log_p m \right\rfloor

    шляхом повторного ділення на ;

  • якщо e > \texttt{flog}(m,p), ми множимо відповідь на p^{e-\texttt{flog}(m,p)}.

Складність становить \mathcal{O}(\sqrt{n}).

def flog(m,p):
    t=0
    while m>=p:
        m//=p
        t+=1
    return t

def g(n,m):
    ans=1;x=n;i=2
    while i*i<=x:
        e=0
        while x%i==0:
            x//=i
            e+=1
        if e:
            t=flog(m,i)
            if e>t: ans*=i**(e-t)
        i+=1
    if x>1:
        t=flog(m,x)
        if 1>t: ans*=x**(1-t)
    return ans

for _ in range(int(input())):
    n,m=map(int,input().split())
    print(g(n,m))