Processing math: 100%
알고리즘 블로그
article thumbnail

문제 링크

플4치고 쉬운? 문제

1. 풀이

더보기

2

3→2

4→3→2

5→2

6→4→3→2

7→2

8→3→2

9→2

10→3→2

 

주어진 수를 나누지 않는 최솟값 → 어떤 수보다 미만의 모든 수가 주어진 수를 나누게 하는 최솟값

따라서

|{k|(2k)}|×(strength(2)+1)+|{k|(2k)(3k)}|×(strength(3)+1)+|{k|(2k)(3k)(4k)}|×(strength(4)+1)+

를 구해주면 된다.

lcm 단위로 커지기 때문에, 전처리할 strength(k)의 종류가 그리 많지 않다는 것을 알 수 있다.

실제로 해보면 42인가까지가 딱 맞다. 넘기면 오버플로우 나는 딱 그런 지점이더라.

 

<c++ />
#include <bits/stdc++.h> using namespace std; using ll = long long; #define rep(i,a,b) for (auto i = (a); i <= (b); ++i) ll a, b; ll d[43], l[43]; int main() { scanf("%lld %lld", &a, &b); d[1] = 1; rep(i,2,42) d[i] = lcm(i,d[i-1]); l[2] = 1; rep(i,3,42) { rep(j,2,42) { if (i%d[j] != 0) { l[i] = l[j]+1; break; } } } ll w = b-a+1, ans = 0; rep(i,2,42) { ll v = b/d[i]-(a-1)/d[i]; ans += (w-v)*(l[i]+1); w = v; } printf("%lld", ans); }

 

profile

알고리즘 블로그

@도훈.

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!