原文:

给定三个整数 lrm ,任务是求【l,r】范围内一个数的被 m 整除的概率

欧拉全能性函数是{1,2,3,…,n}中相对于 n 为素数的数的计数,即 gcd(最大公约数)n 为 1 的数。

示例:

输入: l = 1,r = 5,m = 2 输出: 0.6 说明: n = 1,2,3,4,5 的欧拉全能性函数分别为{1,1,2,2,4}。 可被 m(= 2)整除的欧拉全能函数的计数为 3。 因此,所需概率为 3/5 = 0.6

输入: l = 1,r = 7,m = 4 输出: 0.142 解释: n = 1,2,3,…7 的欧拉全能性函数分别为{1,1,2,2,4,2,6}。 可被 m(= 4)整除的欧拉全能性函数的计数为 1。 因此,所需概率为 1/7 = 0.142

方法:思路是预先计算,在给定范围内迭代,计算可被 m 整除的数,计算概率。

对于的计算,使用欧拉乘积公式:

其中pit3】是 n 的质因数。

对于*(l<= n<= r)*的每个质因数 i ,执行以下步骤:

  • 【1,n】中减去 i 的所有倍数。
  • 通过重复除以 i 来更新 n
  • 如果减少的 n 大于 1 ,则从结果中去除所有倍数的 n

质因数的计算采用厄拉多塞法的筛。给定范围内的概率为计数/(l–r 1)

下面是上述方法的实现:

c

// c   program to implement
// the above approach
#include 
using namespace std;
#define size 1000001
// seieve of erotosthenes
// to compute all primes
void seiveoferatosthenes(int* prime)
{
    prime[0] = 1, prime[1] = 0;
    for (int i = 2; i * i < 1000001; i  ) {
        // if prime
        if (prime[i] == 0) {
            for (int j = i * i; j < 1000001;
                 j  = i) {
                // mark all its multiples
                // as non-prime
                prime[j] = 1;
            }
        }
    }
}
// function to find the probability of
// euler's totient function in a given range
float probabiltyeuler(int* prime, int l,
                      int r, int m)
{
    int* arr = new int[size]{ 0 };
    int* eulertotient = new int[size]{ 0 };
    int count = 0;
    // initializing two arrays
    // with values from l to r
    // for euler's totient
    for (int i = l; i <= r; i  ) {
        // indexing from 0
        eulertotient[i - l] = i;
        arr[i - l] = i;
    }
    for (int i = 2; i < 1000001; i  ) {
        // if the current number is prime
        if (prime[i] == 0) {
            // checking if i is prime factor
            // of numbers in range l to r
            for (int j = (l / i) * i; j <= r;
                 j  = i) {
                if (j - l >= 0) {
                    // update all the numbers
                    // which has prime factor i
                    eulertotient[j - l]
                        = eulertotient[j - l]
                          / i * (i - 1);
                    while (arr[j - l] % i == 0) {
                        arr[j - l] /= i;
                    }
                }
            }
        }
    }
    // if number in range has a
    // prime factor > sqrt(number)
    for (int i = l; i <= r; i  ) {
        if (arr[i - l] > 1) {
            eulertotient[i - l]
                = (eulertotient[i - l] / arr[i - l])
                  * (arr[i - l] - 1);
        }
    }
    for (int i = l; i <= r; i  ) {
        // count those which are divisible by m
        if ((eulertotient[i - l] % m) == 0) {
            count  ;
        }
    }
    // return the result
    return (1.0 * count / (r   1 - l));
}
// driver code
int main()
{
    int* prime = new int[size]{ 0 };
    seiveoferatosthenes(prime);
    int l = 1, r = 7, m = 3;
    cout << probabiltyeuler(prime, l, r, m);
    return 0;
}

java 语言(一种计算机语言,尤用于创建网站)

// java program to implement
// the above approach
import java.util.*;
class gfg{
static final int size = 1000001;
// seieve of erotosthenes
// to compute all primes
static void seiveoferatosthenes(int []prime)
{
    prime[0] = 1;
    prime[1] = 0;
    for (int i = 2; i * i < 1000001; i  )
    {
        // if prime
        if (prime[i] == 0)
        {
            for (int j = i * i; j < 1000001; j  = i)
            {
                // mark all its multiples
                // as non-prime
                prime[j] = 1;
            }
        }
    }
}
// function to find the probability of
// euler's totient function in a given range
static float probabiltyeuler(int []prime, int l,
                             int r, int m)
{
    int[] arr = new int[size];
    int []eulertotient = new int[size];
    int count = 0;
    // initializing two arrays
    // with values from l to r
    // for euler's totient
    for (int i = l; i <= r; i  )
    {
        // indexing from 0
        eulertotient[i - l] = i;
        arr[i - l] = i;
    }
    for (int i = 2; i < 1000001; i  )
    {
        // if the current number is prime
        if (prime[i] == 0)
        {
            // checking if i is prime factor
            // of numbers in range l to r
            for (int j = (l / i) * i; j <= r; j  = i)
            {
                if (j - l >= 0)
                {
                    // update all the numbers
                    // which has prime factor i
                    eulertotient[j - l] = eulertotient[j - l] /
                                                    i * (i - 1);
                    while (arr[j - l] % i == 0)
                    {
                        arr[j - l] /= i;
                    }
                }
            }
        }
    }
    // if number in range has a
    // prime factor > math.sqrt(number)
    for (int i = l; i <= r; i  )
    {
        if (arr[i - l] > 1)
        {
            eulertotient[i - l] = (eulertotient[i - l] / arr[i - l]) *
                                                          (arr[i - l] - 1);
        }
    }
    for (int i = l; i <= r; i  )
    {
        // count those which are divisible by m
        if ((eulertotient[i - l] % m) == 0)
        {
            count  ;
        }
    }
    // return the result
    return (float) (1.0 * count / (r   1 - l));
}
// driver code
public static void main(string[] args)
{
    int []prime = new int[size];
    seiveoferatosthenes(prime);
    int l = 1, r = 7, m = 3;
    system.out.print(probabiltyeuler(prime, l, r, m));
}
}
// this code is contributed by sapnasingh4991

python 3

# python3 program to implement
# the above approach
size = 1000001
# seieve of erotosthenes
# to compute all primes
def seiveoferatosthenes(prime):
    prime[0] = 1
    prime[1] = 0
    i = 2
    while(i * i < 1000001):
        # if prime
        if (prime[i] == 0):
            j = i * i
            while(j < 1000001):
                # mark all its multiples
                # as non-prime
                prime[j] = 1
                j = j   i
        i  = 1
# function to find the probability of
# euler's totient function in a given range
def probabiltyeuler(prime, l, r, m):
    arr = [0] * size
    eulertotient = [0] * size
    count = 0
    # initializing two arrays
    # with values from l to r
    # for euler's totient
    for i in range(l, r   1):
        # indexing from 0
        eulertotient[i - l] = i
        arr[i - l] = i
    for i in range(2, 1000001):
        # if the current number is prime
        if (prime[i] == 0):
            # checking if i is prime factor
            # of numbers in range l to r
            for j in range((l // i) * i, r   1, i):
                if (j - l >= 0):
                    # update all the numbers
                    # which has prime factor i
                    eulertotient[j - l] = (eulertotient[j - l] //
                                                   i * (i - 1))
                    while (arr[j - l] % i == 0):
                        arr[j - l] =  arr[j - l] // i
    # if number in range has a
    # prime factor > math.sqrt(number)
    for i in range(l, r   1):
        if (arr[i - l] > 1):
            eulertotient[i - l] = ((eulertotient[i - l] //
                                             arr[i - l]) *
                                       (arr[i - l] - 1))
    for i in range(l, r   1): 
        # count those which are divisible by m
        if ((eulertotient[i - l] % m) == 0):
            count  = 1
    # return the result
    return (float)(1.0 * count / (r   1 - l))
# driver code
prime = [0] * size
seiveoferatosthenes(prime)
l, r, m = 1, 7, 3
print(probabiltyeuler(prime, l, r, m))
# this code is contributed by divyeshrabadiya07

c#

// c# program to implement
// the above approach
using system;
class gfg{
static readonly int size = 1000001;
// seieve of erotosthenes
// to compute all primes
static void seiveoferatosthenes(int []prime)
{
    prime[0] = 1;
    prime[1] = 0;
    for (int i = 2; i * i < 1000001; i  )
    {
        // if prime
        if (prime[i] == 0)
        {
            for (int j = i * i; j < 1000001; j  = i)
            {
                // mark all its multiples
                // as non-prime
                prime[j] = 1;
            }
        }
    }
}
// function to find the probability of
// euler's totient function in a given range
static float probabiltyeuler(int []prime, int l,
                             int r, int m)
{
    int[] arr = new int[size];
    int []eulertotient = new int[size];
    int count = 0;
    // initializing two arrays
    // with values from l to r
    // for euler's totient
    for (int i = l; i <= r; i  )
    {
        // indexing from 0
        eulertotient[i - l] = i;
        arr[i - l] = i;
    }
    for (int i = 2; i < 1000001; i  )
    {
        // if the current number is prime
        if (prime[i] == 0)
        {
            // checking if i is prime factor
            // of numbers in range l to r
            for (int j = (l / i) * i; j <= r; j  = i)
            {
                if (j - l >= 0)
                {
                    // update all the numbers
                    // which has prime factor i
                    eulertotient[j - l] = eulertotient[j - l] /
                                                       i * (i - 1);
                    while (arr[j - l] % i == 0)
                    {
                        arr[j - l] /= i;
                    }
                }
            }
        }
    }
    // if number in range has a
    // prime factor > math.sqrt(number)
    for (int i = l; i <= r; i  )
    {
        if (arr[i - l] > 1)
        {
            eulertotient[i - l] = (eulertotient[i - l] / arr[i - l]) *
                                                        (arr[i - l] - 1);
        }
    }
    for (int i = l; i <= r; i  )
    {
        // count those which are divisible by m
        if ((eulertotient[i - l] % m) == 0)
        {
            count  ;
        }
    }
    // return the result
    return (float) (1.0 * count / (r   1 - l));
}
// driver code
public static void main(string[] args)
{
    int []prime = new int[size];
    seiveoferatosthenes(prime);
    int l = 1, r = 7, m = 3;
    console.write(probabiltyeuler(prime, l, r, m));
}
}
// this code is contributed by sapnasingh4991

java 描述语言


**output: 

0.142857**

*时间复杂度: o(nlog(n))辅助空间: o(大小),其中大小表示计算筛的个数。***