Kaosar və GCD#12273

Kaosar və GCD (Həll təhlili)

Problemin Müəllifi:

AlKaosar Hussain

Hazırlayan:

Hasan Saleh (MathModel)

Redaktə edən:

Hasan Saleh (MathModel)

Həll Biz aşağıdakı ədədləri götürürük:

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

və biz istəyirik

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

Bunu etmək üçün təmiz yol, onu ilk ədəddən-ədədə nəzərdən keçirməkdir. Tutaq ki,

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

-nin ilkin faktorizasiyasıdır. Binomların gcd-si də -nin bir böləni olacaq, buna görə də onun forması olacaq

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

bəziləri üçün f_p \le e_p. Bizim işimiz, -ni bölən hər bir ilkin ədəd üçün, hamısında görünən -nin ən kiçik gücünü tapmaqdır

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

O "ən kiçik güc" tam olaraq

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

amma heç vaxt mənfi olmur (əgər mənfi olarsa, sadəcə qoyuruq).

Bu niyə doğrudur? Bir ilkin ədəd götürün və -nin -adic qiymətləndirməsi olduğunu düşünün, yəni n = p^e \cdot r və \gcd(r,p)=1. İndi k = p^t olan binomiyaya baxın, burada

t = \bigl\lfloor \log_p m \bigr\rfloor \quad\text{belə ki}\quad p^t \le m < p^{t+1}.

Bu bizim aralığımızdadır 1 \le k \le m. Bu xüsusi üçün yoxlamaq olar (bu standart bir faktdır və -dəki daşımalara baxaraq və ya faktoriallara baxaraq sübut edilə bilər) ki

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

Beləliklə, bu xüsusi üçün -dəki -nin gücü tam olaraq p^{e-t}-dir. Bu artıq göstərir ki, gcd daha çox p^{e-t}-dən çox ola bilməz.

İkinci hissə budur ki, hər hansı k \le m üçün siz e - t-dən daha kiçik bir -gücü əldə edə bilməzsiniz. İntuitiv olaraq: binomda daha çox güclərini "öldürmək" üçün, -da daha çox faktoru içərməlidir, lakin -ə qədər siz yalnız \lfloor \log_p m \rfloor faktoru əldə edə bilərsiniz, buna görə də binomda olan eksponent \ge e - \lfloor \log_p m \rfloor qalır. Buna görə də, aralığında olan bütün -lar üçün minimum tam olaraq

\min_{1 \le k \le m} v_p\bigl(\binom{n}{k}\bigr) = e - \bigl\lfloor \log_p m \bigr\rfloor \quad (\text{amma $0$-dan aşağı deyil}).

Bunu -ni bölən bütün ilkin ədədlər üçün bir araya gətirdikdə, biz alırıq

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

Kod tam olaraq bunu edir:

  • -ni -lərə və -lərə ayırın;

  • hər bir üçün \texttt{flog}(m,p)-ni hesablayın ki, bu da tam olaraq

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

    -ni -yə təkrarlayaraq bölməklə;

  • əgər e > \texttt{flog}(m,p)-dirsə, cavabı p^{e-\texttt{flog}(m,p)} ilə vururuq.

Komplekslik \mathcal{O}(\sqrt{n})-dir.

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))