[L, R] 范围内的整数计数不与 [1, R] 中的数字形成任何三角形对
给定整数L和R ,任务是找到范围 [L, R](比如 X)内的整数个数,它们不与范围 [1, R] 内的任何其他整数形成三角形对。
注意:如果 GCD(X, Y)、X/GCD(X, Y) 和 Y/GCD(X, Y) 可以构成三角形的边,则一对整数 {X, Y} 称为三角形对。
例子:
Input: L = 1, R = 5
Output: 3
Explanation: In range [1, 5] there are 3 elements 1, 3 and 5 which does not form any triangular pair.
Other integers 2 and 4 can form triangular pairs. the pair(2, 4) is a triangular pair.
GCD(2, 4) = 2. So the triplet formed is (2, 4/2, 2/2) = (2, 2, 1).
This can be sides of a valid triangle. So only 3 elements are there.
Input: L = 2, R = 6
Output: 2
方法:可以根据以下观察解决问题:
From 1 to N, only 1 and the prime numbers in the range √N to N does not form triangular pairs with any other integers in the range 1 to N
上述观察可以证明如下:
Proof :
For composite numbers: All the composite numbers will form triangular pair with atleast 1 integer.
- Suppose x is a composite number, then x = y * z (y ≥ z, y ≥ 2, z ≥ 2).
- Let a be another number such that a = ((y-1)*z).
- So gcd(a, x) = z, a/gcd(a, x) = y – 1 and x/gcd(a, x) = y.
The triplet {y, y-1, z} would obviously form the sides of a triangle.
For prime numbers: Consider any prime number p in the range [1, N] and any non-coprime number of p, say a.
- So, gcd(a, p) = p, a/gcd(a, p) = a/p and p/gcd(a, p) = 1.
- Now, for the pair {a, p} to form a triangular pair, {1, p, a/p} must form a triangle.
- For that, (p+1) > a/p and 1 + a/p > p, which is possible only when p = a/p or p = √a.
That means, prime number p in range 1 to N can form triangular pair with another integer if p ≤ √N.
So, it can be concluded that in the range [1, N], the integer 1 and prime numbers larger than √N cannot form triangular pairs with any other integers in the range.
So the numbers in range [L, R] which does not form any triangular pair can be calculated by finding such numbers in range [1, L) (say C1) and in range [1, R] (say C2) and then subtracting C1 from C2.
按照下面提到的步骤来实现上述观察:
- 使用 eratosthenes 筛将质数的数量存储到从 1 到 R 的每个整数。
- 如上述观察所示计算 C1 和 C2。
- 从 C2 中减去 C1(比如count )。
- 返回计数作为最终答案。
下面是上述方法的实现:
C++
// C++ code to implement the above approach
#include
using namespace std;
const int M = 1e5;
// Array to store primes upto each
// integer from 1 to N
int p[M + 1];
// Array to store whether each integer from
// 1 to N is prime or not
bool isPrime[M + 1];
// Function to count integers in given
// range which does not form a triangle
// with any other integer in the same
// range for all elements of array
int countNum(int L, int R)
{
memset(isPrime, true, sizeof(isPrime));
isPrime[0] = false, isPrime[1] = false;
// Standard sieve method to store
// which integer is prime
for (int i = 2; i * i <= R; i++) {
if (isPrime[i] == true) {
for (int j = i * i; j <= R;
j += i) {
isPrime[j] = false;
}
}
}
// Prefix sum method to store total primes
// upto any integer till M
p[0] = 0;
for (int i = 1; i <= R; i++) {
p[i] = p[i - 1];
if (isPrime[i]) {
p[i]++;
}
}
// Though 2 is prime but it is even also
p[1] = 1;
int count = p[R] - p[L - 1];
// Returning answer
return count;
}
// Driver Code
int main()
{
int L = 1, R = 5;
// Function call
int answer = countNum(L, R);
cout << answer;
return 0;
}
Java
// Java code to implement the above approach
import java.io.*;
class GFG
{
// Function to count integers in given
// range which does not form a triangle
// with any other integer in the same
// range for all elements of array
public static int countNum(int L, int R)
{
// Array to store primes upto each
// integer from 1 to N
int p[] = new int[100001];
// Array to store whether each integer from
// 1 to N is prime or not
boolean isPrime[] = new boolean[100001];
for (int i = 0; i < 100001; i++)
isPrime[i] = true;
isPrime[0] = false;
isPrime[1] = false;
// Standard sieve method to store
// which integer is prime
for (int i = 2; i * i <= R; i++) {
if (isPrime[i] == true) {
for (int j = i * i; j <= R; j += i) {
isPrime[j] = false;
}
}
}
// Prefix sum method to store total primes
// upto any integer till M
p[0] = 0;
for (int i = 1; i <= R; i++) {
p[i] = p[i - 1];
if (isPrime[i] == true) {
p[i]++;
}
}
// Though 2 is prime but it is even also
p[1] = 1;
int count = p[R] - p[L - 1];
// Returning answer
return count;
}
public static void main(String[] args)
{
int L = 1, R = 5;
// Function call
int answer = countNum(L, R);
System.out.print(answer);
}
}
// This code is contributed by Rohit Pradhan.
Python3
# python3 code to implement the above approach
import math
M = int(1e5)
# Array to store primes upto each
# integer from 1 to N
p = [0 for _ in range(M + 1)]
# Array to store whether each integer from
# 1 to N is prime or not
isPrime = [True for _ in range(M + 1)]
# Function to count integers in given
# range which does not form a triangle
# with any other integer in the same
# range for all elements of array
def countNum(L, R):
global isPrime
isPrime[0], isPrime[1] = False, False
# Standard sieve method to store
# which integer is prime
for i in range(2, int(math.sqrt(R)) + 1):
if (isPrime[i] == True):
for j in range(i*i, R+1, i):
isPrime[j] = False
# Prefix sum method to store total primes
# upto any integer till M
p[0] = 0
for i in range(1, R+1):
p[i] = p[i - 1]
if (isPrime[i]):
p[i] += 1
# Though 2 is prime but it is even also
p[1] = 1
count = p[R] - p[L - 1]
# Returning answer
return count
# Driver Code
if __name__ == "__main__":
L, R = 1, 5
# Function call
answer = countNum(L, R)
print(answer)
# This code is contributed by rakeshsahni
C#
// C# code to implement the above approach
using System;
class GFG
{
static int M = 100000;
// Array to store primes upto each
// integer from 1 to N
static int[] p = new int[M + 1];
// Array to store whether each integer from
// 1 to N is prime or not
static bool[] isPrime = new bool[M + 1];
// Function to count integers in given
// range which does not form a triangle
// with any other integer in the same
// range for all elements of array
static int countNum(int L, int R)
{
for (int i = 0; i < M + 1; i++) {
isPrime[i] = true;
}
isPrime[0] = false;
isPrime[1] = false;
// Standard sieve method to store
// which integer is prime
for (int i = 2; i * i <= R; i++) {
if (isPrime[i] == true) {
for (int j = i * i; j <= R; j += i) {
isPrime[j] = false;
}
}
}
// Prefix sum method to store total primes
// upto any integer till M
p[0] = 0;
for (int i = 1; i <= R; i++) {
p[i] = p[i - 1];
if (isPrime[i]) {
p[i]++;
}
}
// Though 2 is prime but it is even also
p[1] = 1;
int count = p[R] - p[L - 1];
// Returning answer
return count;
}
// Driver Code
public static void Main()
{
int L = 1, R = 5;
// Function call
int answer = countNum(L, R);
Console.Write(answer);
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
3
时间复杂度: O(M*log(log(M))),其中 M 为 1e5
辅助空间: O(M)