Պարզ արտադրիչների վերլուծելը

Յուրաքանչյուր դրական ամբողջ թիվ n ≥ 2 կարելի է ներկայացնել պարզ թվերի արտադրյալի տեսքով.
Թվերի հետ տարբեր գործողություններ (օրինակ, բաժանարարների քանակի հաշվումը, երկու թվերի ամենամեծ ընդհանուր բաժանարարի (GCD) կամ ամենափոքր ընդհանուր բազմապատկի (LCM) վերաբերյալ գտնելը և այլն) հաճախ հնարավոր է հեշտ անել, եթե ունենք տվյալ թվի պարզ արտադրիչների վերլուծությունը։
n թվի (օրինակ՝ 300) պարզ արտադրիչների վերլուծությունը ստանալու համար կարելի է սկսել ամենափոքր պարզ թվից p (2) և, եթե n-ը բաժանելի է p-ի, ապա շարունակաբար բաժանել n-ը այդ p-ով, քանի դեռ դա հնարավոր է (300 / 2 = 150, 150 / 2 = 75)։
Այնուհետև մեծացնել p-ն մեկով (p = 3) և նույն կերպ ստուգել բաժանումը (75 / 3 = 25)։
p-ն մեկով մեծացնելիս ստանում ենք p = 4։ Այս դեպքում չենք կարող n-ը բաժանել p-ի քանի որ n-ն արդեն բաժանել ենք որքան հնարավոր էր 2-ի նախորդ քայլերից մեկում, որը 4-ի բաժանարար է։ Այդ պատճառով n-ի արժեքը 4, 6, 8 և 2-ի ցանկացած բազմապատիկով չենք կարող նորից բաժանել։ Քանի որ աշխատանքի ընթացքում շարժվում ենք փոքրագույն p-ից ավելի մեծ թվերի ուղղությամբ, եթե որևէ փուլում արդեն հայտնաբերել ենք ինչ-որ պարզ բաժանարար, ապա դրա բազմապատիկներն այլևս չեն գործելու։
Հաջորդ քայլում 5-ի բաժանելիությունը ստուգելիս (75 / 5 = 5, ապա 5 / 5 = 1) շարունակում ենք նույն տրամաբանությամբ։ Գործողությունը դադարեցնում ենք այն պահին, երբ p-ն գերազանցում է արժեքը։ Եթե հասնում ենք մի պահի, երբ , ապա մնացած n-ը ինքնին պարզ թիվ է, և այն կարելի է անմիջապես ավելացնել պարզ արտադրիչների ցուցակին։
Այդպիսով, մեր օրինակում 300-ը կարելի է ներկայացնել որպես ։
n = ...                              # n-ը պետք է վերլուծել պարզ արտադրիչների
p, divisors, powers = 1, [], []      # p-ն՝ բաժանարար, divisors-ը՝ պարզ արտադրիչներն են, powers-ը՝ դրանց աստիճանները

while p * p <= n:                    # քանի դեռ p <= sqrt(n)
    p += 1                           # ամեն քայլին p-ն մեծացնում ենք 1-ով
    if n % p != 0:                   # եթե n-ը չի բաժանվում p-ի, անցնում ենք առաջ
        continue
    
    divisors.append(p)               # n % p == 0 => p-ն պարզ բաժանարար է
    powers.append(0)                 # դրա աստիճանը ամենասկզբում 0 է
    while n % p == 0:                # որքան հնարավոր է բաժանում ենք n-ը p-ով
        n //= p
        powers[-1] += 1              # ամեն բաժանումից հետո ավելացնում ենք համապատասխան աստիճանը

if n > 1:                            # եթե p > sqrt(n), ուրեմն n-ը պարզ թիվ
    divisors.append(n)               # ավելացնում ենք n-ը որպես բաժանարար
    powers.append(1)                 # նրա աստիճանը 1 է

print(list(zip(divisors, powers)))   # տպում ենք բաժանարարները և դրանց աստիճանները
Ալգորիթմի յուրաքանչյուր քայլի ընթացքում, եթե տրված բաժանարարով կարելի է բաժանել մեր թիվը, ապա բաժանում ենք և միաժամանակ ավելացնում ենք այդ բաժանարարի աստիճանը:
Մի քանի օրինակ դիտարկենք.
n = 24
  1. p = 2, n = 24 (առաջին քայլին p-ն 1-ից դարձավ 2) n % 2 == 0divisors = [2], powers = [0] n //= 2n = 12, powers = [1] n //= 2n = 6, powers = [2] n //= 2n = 3, powers = [3]
  1. p = 3, n = 3 ⇒ կանգ ենք առնում, քանի որ p * p = 9, որը մեծ է 2-ից
  1. n > 1divisors = [2, 3], powers = [3, 1]
n = 75
  1. p = 2, n = 75
  1. p = 3, n = 75 n % 3 == 0divisors = [3], powers = [0] n //= 3n = 25, powers = [1]
  1. p = 4, n = 25
  1. p = 5, n = 25 n % 5 == 0divisors = [3, 5], powers = [1, 0] n //= 5n = 5, powers = [1, 1] n //= 5n = 1, powers = [1, 2]
  1. p * p > n ⇒ կանգ ենք առնում ⇒ divisors = [3, 5], powers = [1, 2]
n = 84
  1. p = 2, n = 84 n % 2 == 0divisors = [2], powers = [0] n //= 2n = 42, powers = [1] n //= 2n = 21, powers = [2]
  1. p = 3, n = 21 n % 3 == 0divisors = [2, 3], powers = [2, 0] n //= 3n = 7, powers = [2, 1]
  1. p * p > n ⇒ կանգ ենք առնում
  1. n > 1divisors = [2, 3, 7], powers = [2, 1, 1]
n = 31
  1. p = 2, n = 31
  1. p = 3, n = 31
  1. p = 4, n = 31
  1. p = 5, n = 31
  1. p = 6, n = 31
  1. p * p > n ⇒ կանգ ենք առնում
  1. n > 1divisors = [31], powers = [1]

Առաջադրանք

Տրված է n ամբողջ թիվը. Անհրաժեշտ է գտնել n-ի ամենամեծ պարզ բաժանարարը։

Մուտք

Մուտքի միակ տողում տրված է մեկ ամբողջ թիվ n (2 ≤ n ≤ ):

Ելք

Ծրագիրը պետք է տպի n-ի ամենամեծ պարզ բաժանարարը։

Օրինակներ

Մուտք
Ելք
8
2
24
3
75
5
31
31
Բոնուս․ Ինչու՞ չենք ստուգում միայն պարզ թվերը։
Մեր ալգորիթմը բոլոր թվերը անցնում է հերթով 2, 3, 4, … մինչև ։ Թվում է, թե կարելի էր պարզապես անցնել միայն պարզ թվերով մինչև -ը, սակայն նախ պետք է գտնել այն բոլոր պարզ թվերը, որոնք չեն գերազանցում -ը, իսկ դա սովորաբար պահանջում է մոտ գործողություն։ Այսինքն՝ պարզ թվերի գտնելը կարող է ավելի ժամանակատար լինել, քան ուղղակի 2-ից մինչև հերթականությամբ ստուգելը:
Կարո՞ղ եք մտածել այնպիսի իրավիճակ, երբ նախօրոք պարզ թվերի ցուցակ կազմելն ու դրանցով ստուգելը, գուցե, ավելի արդյունավետ լինի:
 

Constraints

Time limit: 2 seconds

Memory limit: 512 MB

Output limit: 1 MB

To check your solution you need to sign in
Sign in to continue