当前位置: 首页 > news >正文

数学知识——欧拉函数

欧拉函数

1 ∼ N 1∼N 1N 中与 N N N互质的数的个数被称为欧拉函数,记为 ϕ ( N ) \phi(N) ϕ(N)

欧拉函数

对于 N = p 1 α 1 p 2 α 2 p 3 α 3 . . . p k α k N=p_1^{\alpha_1}p_2^{\alpha_2}p_3^{\alpha_3}...p_k^{\alpha_k} N=p1α1p2α2p3α3...pkαk,有 ϕ ( N ) = N × p 1 − 1 p 1 × p 2 − 1 p 2 . . . × p k − 1 p k \phi(N)=N×\frac{p_1-1}{p_1}×\frac{p_2-1}{p_2}...×\frac{p_k-1}{p_k} ϕ(N)=N×p1p11×p2p21...×pkpk1
证明:
根据容斥原理,与 N N N互质的数的个数为 N − N p 1 − N p 2 − N p 3 . . . + N p 1 p 2 + N p 1 p 3 + . . . − N p 1 p 2 p 3 − N p 1 p 2 p 4 − . . . N-\frac{N}{p_1}-\frac{N}{p_2}-\frac{N}{p_3}...+\frac{N}{p_1p_2}+\frac{N}{p_1p_3}+...-\frac{N}{p_1p_2p_3}-\frac{N}{p_1p_2p_4}-... Np1Np2Np3N...+p1p2N+p1p3N+...p1p2p3Np1p2p4N...
其中每一项都含有 N N N,可以把 N N N提出,含有 p i p_i pi数为奇数的项前符号为 − - ,为偶数的项前面的符号为 + + +,即上式可以化简为 N ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) . . . ( 1 − 1 p k ) N(1-\frac{1}{p_1})(1-\frac{1}{p_2})...(1-\frac{1}{p_k}) N(1p11)(1p21)...(1pk1)
时间复杂度为 O ( N ) O(\sqrt N) O(N )

for (int i = 2; i <= a / i; i ++ )
{
    if (a % i == 0)
    {
        while (a % i == 0) a /= i;
        res = res * (i - 1) / i;
    }
}
if (a > 1) res = res * (a - 1) / a;
cout << res << endl;

筛法求欧拉函数

我们可以在线性筛的基础上完成欧拉函数的求解。
1. ϕ ( 1 ) = 1 \phi(1)=1 ϕ(1)=1
2.如果一个数 N N N是质数,那么 ϕ ( N ) = N − 1 \phi(N)=N-1 ϕ(N)=N1
3. ϕ ( p r i m e s [ j ] ∗ i ) \phi(primes[j]*i) ϕ(primes[j]i)分两种情况:
(1). i % p r i m e s [ j ] = = 0 i\%primes[j]==0 i%primes[j]==0时, p r i m e s [ j ] primes[j] primes[j] i i i的最小质因子,所以在 ϕ ( i ) \phi(i) ϕ(i)中, ( 1 − 1 p r i m e s [ j ] ) (1-\frac{1}{primes[j]}) (1primes[j]1)这一项已经考虑过了,只需要将 N N N修正为 p r i m e s [ j ] primes[j] primes[j]倍,最终结果为 p h i [ i ] ∗ p r i m e s [ j ] phi[i] * primes[j] phi[i]primes[j]
(2). i % p r i m e s [ j ] ! = 0 i\%primes[j]!=0 i%primes[j]!=0时, p r i m e s [ j ] primes[j] primes[j]不是 i i i的质因子,只是 p r i m e s [ j ] ∗ i primes[j] * i primes[j]i的最小质因子,因此不仅需要将基数 N N N修正为 p r i m e s [ j ] primes[j] primes[j]倍,还需要补上 1 − 1 / p r i m e s [ j ] 1 - 1 / primes[j] 11/primes[j]这一项,因此最终结果 p h i [ i ] ∗ ( p r i m e s [ j ] − 1 ) phi[i] * (primes[j] - 1) phi[i](primes[j]1)

void get_eulers(int n)
{
    phi[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        if (!st[i])
        {
            primes[cnt++] = i;
            phi[i] = i - 1; 
        }
        for (int j = 0; primes[j] <= n / i; j++)
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0)
            {
                phi[primes[j] * i] = phi[i] * primes[j]; 
                break;
            }
            phi[primes[j] * i] = phi[i] * (primes[j] - 1);
        }
    }
}

可见的点

在一个平面直角坐标系的第一象限内,如果一个点 ( x , y ) (x,y) (x,y) 与原点 ( 0 , 0 ) (0,0) (0,0) 的连线中没有通过其他任何点,则称该点在原点处是可见的。

例如,点 ( 4 , 2 ) (4,2) (4,2) 就是不可见的,因为它与原点的连线会通过点 ( 2 , 1 ) (2,1) (2,1)

部分可见点与原点的连线如下图所示:

在这里插入图片描述

编写一个程序,计算给定整数 N N N 的情况下,满足 0 ≤ x , y ≤ N 0≤x,y≤N 0xyN 的可见点 ( x , y ) (x,y) (xy) 的数量(可见点不包括原点)。

输入格式
第一行包含整数 C C C,表示共有 C C C 组测试数据。

每组测试数据占一行,包含一个整数 N N N

输出格式
每组测试数据的输出占据一行。

应包括:测试数据的编号(从 1 开始),该组测试数据对应的 N 以及可见点的数量。

同行数据之间用空格隔开。

数据范围
1 ≤ N , C ≤ 1000 1≤N,C≤1000 1N,C1000

输入样例:

4
2
4
5
231

输出样例:

1 2 5
2 4 13
3 5 21
4 231 32549

如果所有的点与原点的连接构成直线 y = a b x y=\frac{a}{b}x y=bax的话,本题要求的就是在1到n范围内互质的(a,b)的对数是多少,按照y=x分成上下两部分,本题的答案即为 2 ∗ ϕ ( n ) + 1 2*\phi(n)+1 2ϕ(n)+1

#include <iostream>
using namespace std;
const int N = 1010;
int primes[N], phi[N];
bool st[N];
int n, m, cnt;
void init(int n)
{
    phi[1] = 1;
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i])
        {
            phi[i] = i - 1;
            primes[cnt ++ ] = i;
        }
        for (int j = 0; primes[j] * i <= n; j ++ )
        {
            st[primes[j] * i] = 1;
            if (i % primes[j] == 0)
            {
                phi[primes[j] * i] = phi[i] * primes[j];
                break;
            }
            phi[primes[j] * i] = phi[i] * (primes[j] - 1);
        }
    }
    return ;
}
int main()
{
    init(N - 1);
    cin >> n;
    for (int i = 1; i <= n; i ++ )
    {
        cin >> m;
        int res = 1;
        for (int j = 1; j <= m; j ++ ) res += phi[j] * 2;
        cout << i << " " << m << " " << res << endl;
    }
    return 0;
}

最大公约数

给定整数 N N N,求 1 ≤ x , y ≤ N 1≤x,y≤N 1x,yN G C D ( x , y ) GCD(x,y) GCD(x,y) 为素数的数对 ( x , y ) (x,y) (x,y) 有多少对。

G C D ( x , y ) GCD(x,y) GCD(x,y) 即求 x , y x,y xy 的最大公约数。

输入格式

输入一个整数 N N N

输出格式
输出一个整数,表示满足条件的数对数量。

数据范围
1 ≤ N ≤ 1 0 7 1≤N≤10^7 1N107

输入样例:

4

输出样例:

4

G C D ( x , y ) = p , GCD(x,y)=p, GCD(x,y)=p

G C D ( x / p , y / p ) = 1 GCD(x/p,y/p)=1 GCD(x/p,y/p)=1

x ′ = x / p , y ′ = y / p x'=x/p,y'=y/p x=x/p,y=y/p

1 ≤ x ′ , y ′ ≤ N / p 1\leq x',y'\leq N/p 1x,yN/p

本题可以转换为对于每一个 p p p,在 N / p N/p N/p范围内找互质的数的对数再求和。

答案为 ∑ i = 1 m a x p ∑ j = 1 i 2 ∗ ϕ ( j ) − 1 \sum_{i=1}^{maxp} \sum_{j=1}^{i}2*\phi(j)-1 i=1maxpj=1i2ϕ(j)1

#include <iostream>
using namespace std;
typedef long long ll;
const int N = 1e7 + 10;
bool st[N];
int primes[N], cnt;
int phi[N];
ll s[N];
ll res;
int n;
void init(int n)
{
    s[1] = 1;
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i])
        {
            phi[i] = i - 1;
            primes[cnt ++ ] = i;
        }
        for (int j = 0; primes[j] * i <= n; j ++ )
        {
            st[primes[j] * i] = 1;
            if (i % primes[j] == 0)
            {
                phi[i * primes[j]] = phi[i] * primes[j];
                break;
            }
            phi[primes[j] * i] = phi[i] * (primes[j] - 1);
        }
    }
    for (int i = 2; i <= n; i ++ ) s[i] = s[i - 1] + phi[i];
}
int main()
{
    cin >> n;
    init(n);
    for (int i = 0; i < cnt; i ++ )
        res += 2 * s[n / primes[i]] - 1;
    cout << res << endl;
    return 0;
}

相关文章:

  • WHAT - React 技术栈常用库/工具
  • 用AI无差别转换技术协议到生产工艺
  • 硬件知识积累 单片机+ 光耦 + 继电器需要注意的地方
  • [打印机] 惠普打印机的安装和配置
  • 蓝桥杯速成刷题清单(上)
  • grok 驱动级键盘按键记录器分析
  • 扒光HPM6800系列 | 强到起飞的显控MCU介绍
  • 人工智能在高中教育中的应用现状剖析与挑战应对
  • 【QT】QWidget 概述与核心属性(API)
  • FreeRTOS静态任务创建(2025.4.9巨详细)
  • Vue.js组件化开发实战:从工程化到安全纵深设计
  • 华为数字芯片机考2025合集2已校正
  • Transformer Decoder Block的几个优化方案
  • [Windows] Windows更新暂停器 v1.0.0.0
  • Python内存池机制深度解析
  • 接口自动化测试流程、工具及实践
  • 【RabbitMQ】死信队列
  • 红宝书第三十四讲:零基础学会单元测试框架:Jest、Mocha、QUnit
  • 解决 IntelliJ IDEA 中 Maven 项目左侧项目视图未显示顶层目录问题的详细步骤说明
  • [leetcode]查询区间内的所有素数
  • sublime 网站开发/宁波seo排名外包公司
  • 海口日报社官网/seo综合查询什么意思
  • 广告设计公司介绍范文/网店seo是什么意思
  • 网站建设 软件开发/百度网页收录
  • 抚州哪里有做企业网站的公司/搜索引擎排名营销
  • 青岛国家高新区建设局网站/湖南株洲疫情最新情况