일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- c++
- 미래는_현재와_과거로
- object detection
- dropout
- 가끔은_말로
- 자바스크립트
- 너비 우선 탐색
- 분할 정복
- 가끔은 말로
- BFS
- NEXT
- 플로이드 와샬
- 백트래킹
- 크루스칼
- 문자열
- DP
- Overfitting
- lazy propagation
- 세그먼트 트리
- dfs
- 2023
- 이분 탐색
- 다익스트라
- back propagation
- 조합론
- tensorflow
- 회고록
- 우선 순위 큐
- 알고리즘
- pytorch
Archives
- Today
- Total
Doby's Lab
백준 1124번: 언더프라임 (C++) 본문
https://www.acmicpc.net/problem/1124
1124번: 언더프라임
자연수 X를 소인수분해하면, 곱해서 X가 되는 소수의 목록을 얻을 수 있다. 예를 들어, 12 = 2 × 2 × 3이다. 1은 소수가 아니다. 어떤 수 X를 소인수분해 해서 구한 소수의 목록의 길이가 소수이면,
www.acmicpc.net
Level: Silver I
Solved By: Miller Rabin, Pollard's Rho
소인수분해를 하는 알고리즘이라면 예전에 공부했었던 Pollard's Rho 알고리즘이 기억나서 코드를 가져와서 소인수 분해를 가능하게 했습니다. factors vector의 사이즈를 Miller Rabin에 물려서 소수로 판별이 난다면 res 값을 더해주는 식으로 답을 구했습니다.
#include <iostream>
#include <vector>
#define i128 __int128
#define ull unsigned long long
using namespace std;
vector<ull> factors;
ull power(i128 a, i128 b, i128 mod){ // 피연산자 또한 같은 자료형이어야 overflow가 안 남
a %= mod;
i128 ret = 1; // overflow 방지
while(b > 0){
if(b % 2 == 1) ret = (ret * a) % mod;
a = (a * a) % mod;
b /= 2;
}
return (ull)ret;
}
bool millerRabin(ull n, ull a){
if(a % n == 0) return true;
ull k = n - 1;
while(true){
ull temp = power(a, k, n);
if(temp == n - 1) return true;
if(k % 2) return (temp == 1 || temp == n - 1);
k /= 2;
}
}
bool isPrime(ull n){
if(n == 1) return false;
else if(n == 2) return true;
else if(n % 2 == 0) return false;
else{
ull base[12] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
for(auto a : base){
if(n == a) return true;
if(!millerRabin(n, a)) return false;
}
return true;
}
}
i128 f(i128 x, i128 c, i128 mod){
return ((x * x) % mod + c) % mod;
}
i128 gcd(i128 a, i128 b){
while(true){
i128 temp = a % b;
a = b;
b = temp;
if(b == 0) return a;
}
}
i128 abs128(i128 x){
if(x < 0) return -x;
else return x;
}
void factorize(i128 n){
if(n == 1) return;
else if(n % 2 == 0){
factors.push_back(2);
factorize(n / 2);
return;
}
else if(isPrime(n)){
factors.push_back(n);
return;
}
else{
i128 x, y, c, g = n;
do{
if(g == n){
x = y = rand() % (n - 2) + 2;
c = rand() % 10 + 1;
}
x = ((x * x) % n + c) % n;
y = ((y * y) % n + c) % n;
y = ((y * y) % n + c) % n;
g = gcd(abs128(x - y), n);
} while(g == 1);
factorize(g);
factorize(n / g);
}
}
int main(){
ull A, B; cin >> A >> B;
int res = 0;
for(ull i = A; i <= B; i++){
factors.clear();
factorize(i);
if(isPrime(factors.size())) res++;
}
cout << res;
return 0;
}
728x90
'PS > BOJ' 카테고리의 다른 글
백준 1788번: 피보나치 수의 확장 (C++) (0) | 2023.06.23 |
---|---|
백준 11909번: 배열 탈출 (C++) (0) | 2023.06.20 |
백준 1337번: 올바른 배열 (C++) (0) | 2023.05.29 |
백준 1408번: 24 (C++) (0) | 2023.05.29 |
백준 1297번: TV 크기 (C++) (0) | 2023.05.29 |