양의 정수 범위를 나타내는 두 개의 숫자 시작과 끝이 주어집니다. 목표는 [start, end] 범위에 있는 모든 숫자의 개수를 찾고 해당 숫자의 모든 소인수가 GCD가 1이 되도록 거듭제곱이 되도록 소인수분해를 갖는 것입니다.
숫자가 2 p 로 소인수분해되는 경우 * 3 q * 5 r ... .. 그런 다음 p,q,r의 거듭제곱은 ...gcd=1이어야 합니다.
예를 들어 이해합시다.
예
입력 - 시작 =1, 끝 =10
출력 - GCD가 1인 소인수의 거듭제곱을 갖는 범위의 숫자 개수는 다음과 같습니다. 6
설명 - 숫자는 다음과 같습니다.
2( 2 1 ), 3( 3 1 ), 5( 5 1 ), 7( 7 1 ), 8( 2 3 ) 및 10( 2 1 *5 1 ). 각 소인수분해의 모든 거듭제곱은 gcd가 1입니다.
입력 - 시작 =11, 끝 =20
출력 - GCD가 1인 소인수의 거듭제곱을 갖는 범위의 숫자 개수는 다음과 같습니다. 9
설명 - 숫자는 다음과 같습니다.
11 ( 11 1 ), 12( 3 1 *2 2 ), 13( 13 1 ), 14( 2 1 *7 1 ), 15( 3 1 *5 1 ), 17( 17 1 ), 18( 2 1 *3 2 ), 19( 19 1 ) 및 20( 2 2 *5 1 ). 각 소인수분해의 모든 거듭제곱은 gcd가 1입니다.
아래 프로그램에서 사용된 접근 방식은 다음과 같습니다.
이 접근 방식에서는 시작부터 끝까지 완전하지 않은 범위의 모든 숫자를 계산합니다. 불완전한 힘은 위의 조건을 만족할 것이기 때문입니다. 이를 위해 우리는 모든 완벽한 능력을 찾아 총계에서 제거할 것입니다.
답은 =start-end +1 - (범위[start,end]에서 완전제곱수인 숫자의 개수)입니다.
- 범위 변수를 입력으로 시작하고 끝냅니다.
- 벡터 vec를 사용하여 3보다 큰 거듭제곱을 저장합니다.
- 완전제곱수를 저장하려면 집합을 사용하세요.
- 완전제곱이 아닌 숫자를 저장하려면 sett_2 집합을 사용하세요.
- 함수 계산()은 벡터 vec를 채우고 sett 및 sett_2를 설정합니다. 완전제곱수, 비완전제곱수 및 거듭제곱인 수를 구분하려면>3.
- i=2에서 i
까지 for 루프를 사용하는 순회 - 설정할 완전 거듭제곱 i*i를 삽입합니다.
- IF sett.find(i) !=sett.end())가 true를 반환하면 i는 완전제곱수이고 sett에 있으므로 아무 것도 하지 않습니다.
- 현재 숫자의 거듭제곱이 큰 값보다 작아질 때까지 while 루프를 실행합니다.
- 짝수 거듭제곱은 완전제곱이고 집합이므로 sett_2에 홀수 거듭제곱을 삽입합니다.
- 마지막에 for 루프를 사용하여 벡터 vec에 sett_2의 정렬된 값을 삽입합니다.
- 함수 GCD_1(long int start, long int end)은 범위를 입력으로 사용하고 GCD가 1인 소인수 거듭제곱을 갖는 범위의 숫자 개수를 반환합니다.
- calc()를 호출합니다.
- per_sq =floor(sqrtl(end)) - floor(sqrtl(start - 1))과 같은 범위의 완전제곱수를 계산합니다.
- upper_bound(vec.begin(), vec.end(), end) - vec.begin()을 사용하여 vec에서 시작의 상위 값을 계산합니다.
- bottom =lower_bound(vec.begin(), vec.end(), start) - vec.begin()을 사용하여 vec의 end 값이 유사하게 낮습니다.
- per_pow =per_sq + (상단 - 하단)으로 완전 거듭제곱을 계산합니다.
- 답은 count =(end - start + 1) - per_pow입니다.
- 마지막에 결과로 카운트를 반환합니다.
예시
#include <bits/stdc++.h> using namespace std; #define size 1000005 #define large 1e18 vector < long int > vec; set < long int > sett; set < long int > sett_2; void calculate() { for (long int i = 2; i < size; i++) { sett.insert(i * i); if (sett.find(i) != sett.end()) { continue; } long int total = i; while (i * i <= large / total) { total *= (i * i); sett_2.insert(total); } } for (auto it: sett_2) { vec.push_back(it); } } long int GCD_1(long int start, long int end) { calculate(); long int per_sq = floor(sqrtl(end)) - floor(sqrtl(start - 1)); long int top = upper_bound(vec.begin(), vec.end(), end) - vec.begin(); long int bottom = lower_bound(vec.begin(), vec.end(), start) - vec.begin(); long int per_pow = per_sq + (top - bottom); long int count = (end - start + 1) - per_pow; return count; } int main() { long int start = 10, end = 40; cout << "Count of numbers in a range having GCD of powers of prime factors equal to 1 are: " << GCD_1(start, end); return 0; }
위의 코드를 실행하면 다음 출력이 생성됩니다 -
출력
Count of numbers in a range having GCD of powers of prime factors equal to 1 are: 7