algorithm

λ°±μ€€ 1630

rkawk 2024. 4. 8. 22:12

문제

더보기

μ˜€λ―Όμ‹ μ„±κ³΅

 

μ˜€λ―Όμ‹μ„ λ§Œμ‘±ν•˜λŠ” 수: 1보닀 ν¬κ±°λ‚˜ κ°™κ³ , N보닀 μž‘κ±°λ‚˜ 같은 λͺ¨λ“  μžμ—°μˆ˜λ‘œ λ‚˜λˆ„μ–΄ λ–¨μ–΄μ§€λŠ” 수.

μ˜μ‹μ΄μ™€ λ‹€μ†œμ΄λŠ” N이 μ£Όμ–΄μ‘Œμ„ λ•Œ, μ˜€λ―Όμ‹μ„ λ§Œμ‘±ν•˜λŠ” κ°€μž₯ μž‘μ€ μˆ˜κ°€ κΆκΈˆν•΄μ‘Œλ‹€. κ·Έ 수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 μžμ—°μˆ˜ N이 μ£Όμ–΄μ§„λ‹€. N은 1,000,000보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€.

좜λ ₯

첫째 쀄에 μ£Όμ–΄μ§„ μž…λ ₯에 λŒ€ν•΄ μ˜€λ―Όμ‹μ„ λ§Œμ‘±ν•˜λŠ” κ°€μž₯ μž‘μ€ μžμ—°μˆ˜λ₯Ό 987654321둜 λ‚˜λˆˆ λ‚˜λ¨Έμ§€λ₯Ό 좜λ ₯ν•œλ‹€.

풀이

1 λΆ€ν„° μ—°μ†λ˜λŠ” μ¦κ°€ν•˜λŠ” μ •μˆ˜λ“€μ˜ κ³±μ…ˆμ—μ„œ μ΅œμ†Œκ³΅λ°°μˆ˜κ°€ μƒκΈ°λŠ” κ·œμΉ™μ„ 찾으면 λ¬Έμ œκ°€ ν’€λ¦°λ‹€.

λͺ¨λ“  μˆ˜λŠ” 1둜 λ‚˜λˆ„μ–΄ λ–¨μ–΄μ§€λ―€λ‘œ 1은 μ œμ™Έν•˜κ³ , 2λΆ€ν„° μ—°μ†ν•΄μ„œ λ‚˜μ—΄ν•΄λ³΄λ©΄

2, 3, 2^2, 5, 2 * 3, 7, 2^3, 3^2 와 같이 λ‚˜νƒ€λ‚Ό 수 μžˆλ‹€.

 

μˆœμ„œλŒ€λ‘œ κ³±ν•΄κ°€λ©΄μ„œ μ΅œμ†Œκ³΅λ°°μˆ˜λ₯Ό ν™•μΈν•˜λ©΄ μš°μ„ μ μœΌλ‘œ

1.  lcm(a, b) = (a * b) % gcd(a, b) 이닀. a, bκ°€ μ„œλ‘œμ†Œμ΄λ©΄ gcd(a, b)λŠ” 1이고, a, b쀑 ν•˜λ‚˜κ°€ μ†Œμˆ˜λΌλ©΄ 항상 μ„œλ‘œμ†Œμ΄λ―€λ‘œ

a, b λ‘˜μ€‘ ν•˜λ‚˜κ°€ μ†Œμˆ˜λΌλ©΄ lcm(a, b) = a * b이닀. λΌλŠ” 것을 μ•Œ 수 μžˆλ‹€.

 

2. lcm(a, b) = (a * b) % gcd(a, b)λ₯Ό λ‹€μ‹œ κΈ°μ–΅ν•΄μ„œ, μ†Œμˆ˜μ˜ NμŠΉμ— ν•΄λ‹Ήν•˜λŠ” μžμ—°μˆ˜κ°€ λ‚˜μ˜€λ©΄ lcm 계산 κ³Όμ •μ—μ„œ 항상 gcd둜 mod 연산을 ν•΄μ£Όμ—ˆκΈ° λ•Œλ¬Έμ— νŠΉμ • μ†Œμˆ˜μ˜ N - 1승 κΉŒμ§€λ§Œ μ΅œμ†Œκ³΅λ°°μˆ˜κ°€ λ§Œμ‘±ν•˜κ³  μžˆλ‹€λŠ” 사싀 을 μ•Œμˆ˜μžˆλ‹€.

예λ₯Ό λ“€μ–΄, 1 λΆ€ν„° 7 κΉŒμ§€ κ³±ν–ˆμ„λ•Œ 이전에 계산 과정에 따라 2^2 * 3 * 5 * 7 μ΄λΌλŠ” 것을 μ•Œ 수 μžˆλ‹€. 8은 2^3이고, lcmμ—μ„œ 2κ°€ ν•˜λ‚˜ λΆ€μ‘±ν•˜λ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€.

 

κ·ΈλŸ¬λ―€λ‘œ 두가지 쑰건을 λ§Œμ‘±ν•˜κ²Œ κ΅¬ν˜„ν•˜λ©΄ λœλ‹€.

 

더보기
#include <iostream>
#include <vector>
#define ll long long
using namespace std;
int isPrime[1000001], isTime[1000001];
vector<int>priArr;
void pcheck() {
    for(int i=2; i <= 1000000; i++) isPrime[i] = i;
    for(int i=2; i*i <=1000000; i++) {
        if(!isPrime[i]) continue;
        for(int j = i*i; j<=1000000; j += i) isPrime[j] = 0;
    }
    for(int i=2; i<=1000000; i++)
        if(isPrime[i]) priArr.push_back(i);
}
int main() {
    ll a = 1, N;
    cin>>N;
    pcheck();
    for(auto e : priArr) {
        long long check = e;
        while(check * e <= 1000000){
            check = check * e;
            isTime[check] = e;
        }
    }
    for(int i=1; i<=N; i++){
        if(isPrime[i])
            a = (a*i)%987654321;
        else {
            if(isTime[i])
                a = (a*isTime[i])%987654321;
        }
    }
    cout<<a;
}