algorithm

λ°±μ€€ 21870

rkawk 2024. 7. 30. 22:53

문제

풀이

μ™Όμͺ½μ—μ„œ λΆ€ν„° 선택할 경우 선택할 수 μžˆλŠ” μ›μ†Œμ˜ κ°œμˆ˜λŠ” ⌊|S|/2⌋, 였λ₯Έμͺ½λΆ€ν„° 선택할 경우 선택할 수 μžˆλŠ” μ›μ†Œμ˜ κ°œμˆ˜λŠ”  ⌈|S|/2⌉둜 μ •ν•΄μ Έ μžˆλ‹€.

ν•œ λ°©ν–₯을 μ„ νƒν•˜κ²Œ λœλ‹€λ©΄ ν•΄λ‹Ή λ°©ν–₯의 μ›μ†Œ μ „μ²΄μ˜ GCDλ₯Ό μ„ νƒν•˜κ³  남은 μ›μ†Œλ“€μ—μ„œ λ‹€μ‹œ λ°©ν–₯을 μ„ νƒν•˜λŠ” νƒœμŠ€ν¬λ₯Ό μ§„ν–‰ν•˜κ²Œ λœλ‹€.

κ·ΈλŸ¬λ―€λ‘œ μ™Όμͺ½μ„ μ„ νƒν•˜λŠ” 경우, 였λ₯Έμͺ½μ„ μ„ νƒν•˜λŠ” κ²½μš°μ— λŒ€ν•œ λͺ¨λ“  경우의 수λ₯Ό ꡬ해 μ΅œλŒ“κ°’μ„ κ΅¬ν•˜λ©΄ ν’€λ¦¬λŠ” λ¬Έμ œλ‹€.

 

λ°°μ—΄μ˜ ν¬κΈ°λŠ” 2*10^5이고, a<=2*10^5, b<=2*10^5라 ν–ˆμ„λ•Œ gcd(a, b)의 μ‹œκ°„λ³΅μž‘λ„λŠ” log min(a, b)κ°€ λœλ‹€.

κ·ΈλŸ¬λ―€λ‘œ 전체 배열에 λŒ€ν•΄ gcd 연산을 ν•˜κ²Œ λ˜λŠ” 이 μ•Œκ³ λ¦¬μ¦˜μ€ O(N log min(a, b))이닀.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int N, arr[200001], ans;
int gcd(int a, int b) {
    if(b == 0) return a;
    return gcd(b, a%b);
}
int getGcd(int l, int r) {
    int g = arr[l];
    for(int i=l+1; i<=r; i++) {
        g = gcd(g, arr[i]);
    }
    return g;
}
int solve(int l, int r, int n) {
    if(n == 1) return max(arr[l], arr[r]);
    int arrsize = n/2;
    int right = getGcd(l, l+arrsize-1) + solve(l+arrsize, r, n-arrsize);

    int left = getGcd(l+arrsize, r) + solve(l,l+arrsize-1, arrsize);
    return max(left, right);
}
int main() {
    cin>>N;
    for(int i=0; i<N; i++) {
        cin>>arr[i];
    }
    cout<<solve(0, N-1, N);
}