레야몬
[C++] 11689번 GCD(n, k) = 1 - 수학, 정수론, 오일러 피 함수 본문
1. 문제를 읽고 이해한다.
자연수 n \(1\leq n\leq 10^{12}\)
GCD(n, k) = 1을 만족하는 자연수 $$ 1 \leq k \leq n $$ 의 개수 출력
2. 문제를 익숙한 용어로 재정의한다.
n과 서로소인 수의 개수 출력(1도 포함)
3. 어떻게 해결할지 계획을 세운다.
- 에라토스테네스의 체로 소수를 구하기( $$ \sqrt{n} $$ 가지) O( $$ \sqrt{n} $$ )
- 오일러 피 하수(Euler phi function)을 사용하기
4. 계획을 검증한다.
O( $$ \sqrt{n} $$ ) = $$ \10^{6} $$ = 1, 000, 000
5. 프로그램으로 구현한다.
6. 어떻게 풀었는지 돌아보고, 개선할 방법이 있는지 찾아본다.
- n과 서로소가 아니라 n의 소인수를 구해야 한다.
- $$ \sqrt{n} $$개의 배열이 아닌 +1개의 배열이 필요하다.
- ll(long long)의 범위를 넘어간다.
- 2씩 +해서 탐색하면 짝수를 모두 제거해서 소요 시간을 획기적으로 줄일 수 있다.
결국 여차 저차 해서 완성된 코드
#include <iostream>
#include <math.h>
using namespace std;
typedef long long ll;
ll N;
ll pi()
{
//sqrt(N)까지만 소수를 확인해주면 나머지 소수도 확인할 수 있다.
ll ans = N;
int sqrtn = int(sqrt(N));
for(int i=2; i<=sqrtn; ++i) {
//N이 i로 처음으로 나눠질 경우 i는 소수이다.
if(!(N%i)) {
//i를 소인수로 더 이상 가지지 않을 때까지 N을 나눠준다.
while(!(N%i)) N/=i;
ans = ans - ans/i;
}
}
//sqrt(N)보다 큰 소수가 있을 수 있으므로 한 번더 나눠준다.
if(N>1)
ans = ans - ans/N;
return ans;
}
int main()
{
cin.tie(0)->sync_with_stdio(0);
cin >> N;
cout << pi();
return 0;
}
<오일러 피 함수 1>
https://m.blog.naver.com/hongjg3229/221795417061
오일러 파이 함수와 오일러 정리
ps에 가끔 등장하는 것 같아서 정리해두려고 한다. 오일러 파이 함수 오일러 파이 함수는 "임의의 양...
blog.naver.com
<에라토스테네스의 체>
[Algorithm] 에라토스테네스의 체
에라토스테네스의 체 란? 소수를 판별하는 알고리즘이다. 소수들을 대량으로 빠르고 정확하게 구하는 방법이다. 단일 숫자 소수 여부 확인 어떤 수의 소수의 여부를 확인 할 때는, 특정한 숫자
velog.io
<짝수를 제거한 코드(풀어야 볼 수 있습니다.)
https://www.acmicpc.net/source/15488257
로그인
www.acmicpc.net
※현재 고등학교 등교 중인 학생입니다. 이제 알고리즘을 본격적으로 공부하기 시작해서 아직 초보입니다. 혹시 제가 잘못 알고 있는 점이나 더 좋은 풀이 방법이 있어 댓글에 남겨주시면 감사히 하나하나 열심히 읽어보겠습니다. 좋아요, 단순한 댓글 한마디라도 저에겐 큰 힘이 됩니다! 감사합니다.
'알고리즘 > 백준' 카테고리의 다른 글
[C++] 14725번 개미굴 - 자료 구조, 문자열, 트리, 트라이 (0) | 2022.10.19 |
---|---|
[C++] 16287번 Parcel - DP, 중간에서 만나기 (0) | 2022.10.18 |
[C++] 11400번 단절선 - 그래프 이론, 그래프 탐색, DFS, 단절점과 단절선 (0) | 2022.10.17 |
[C++] 11266번 단절점 - 그래프 이론, 단절점과 단절선 (0) | 2022.10.13 |
[C++] 6549번 히스토그램에서 가장 큰 직사각형 - 자료 구조, 세그먼트 트리, 분할 정복, 스택 (0) | 2022.10.12 |