首页 > 其他分享 >欧拉函数

欧拉函数

时间:2023-11-19 09:12:46浏览次数:36  
标签:... p1 函数 int pk 欧拉

欧拉函数

定义法

定义法求欧拉函数是O(sqrt(n))的时间复杂度
只可以求单个数的欧拉函数,

/*
    欧拉函数φ的定义, φ(i)表示从[1, i]之间和i互质的数量(a和b互质即gcd(a, b) == 1)
    欧拉函数是积性函数, 例如a, b都为质数, 那么φ(a*b) = φ(a) * φ(b), 递推式为φ(a*b) = φ(a)*φ(b)*gcd(a,b) / φ(gcd(a,b)) (证明暂时搁置)
    
    一个数N = p1^b1 * p2^b2 * p3^b3 * ... * pk^bk;(p为质数)
    φ(N) = φ(p1^b1) * φ(p2^b2) * φ(p3^b3) * ... * φ(pk^bk);
    φ(p^b) = p^b - p^(b-1); [1, p^b]一共有p^b个数, 不和p^b的数有p, 2p, 3p, ... p^(b-1) * p, 总共p^(b-1)个, 剩下的就是满足要求的即 p^b - p^(b-1)
    φ(p^b) = p^b * (1 - 1/p);
    φ(N) = p1^b1 * (1 - 1/p1) * p1^b1 * (1 - 1/p1) * ... pk^bk * (1 - 1/pk);
    φ(N) = (p1^b1 * p1^b1 * ... * pk^bk) * (1 - 1/p1) * (1 - 1/p2) * ... * (1 - 1/pk);
    因为N = p1^b1 * p2^b2 * ... * pk^bk;
    φ(N) = N * (1 - 1/p1) * (1 - 1/p2) * ... * (1 - 1/pk);
    就可以通过分解N的质因数求出来φ(N), 由此也可以看出, 一个数欧拉函数的大小和质数的次幂无关
    
    试除法分解质因数是O(sqrt(n))的, 所以求φ(N)也就是O(sqrt(n))的
    具体见代码
*/
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

int n, m;

int main()
{
    int T;
    cin >> T;
    while (T -- )
    {
        cin >> n;
        int res = n;
        for (int i = 2; i <= n / i; i ++ )
        {
            if (n % i == 0) 
            {
                res = res / i * (i - 1); // 相当于res * (1 - 1 / i), 这样是为了防止出现小数, 下取整没了, 最主要的就是这里
                while (n % i == 0) n /= i;
            }
        }
        if (n != 1) res = res / n * (n - 1); // 这里不要忘记
        cout << res << endl;
    }
    return 0;
}

一个数欧拉函数的大小和质因数次幂无关

筛法求欧拉函数

O(n)

/*
    线性筛可以求出很多附加的东西
    具体会在代码里写注释
*/

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 1000010;

int n;
int primes[N], cnt;
bool st[N];
int phi[N]; // phi[i] 是i的欧拉函数
LL sum;

int main()
{
    cin >> n;
    phi[1] = 1; // 1的欧拉函数是1, 需要手动写上
    for (int i = 2; i <= n; i ++ )
    {
        if (st[i] == 0)
        {
            primes[ ++ cnt] = i;
            sum += phi[i] = i - 1; // 首先如果i是质数, 质数和所有数都互质(除了它自己), 那么对于质数i的φ, 就是i - 1
        }
        for (int j = 1; primes[j] <= n / i; j ++ )
        {
            st[i * primes[j]] = true;
            if (i % primes[j] == 0) // 如果i % pj == 0 那么pj就是i的最小质因数(这点在线性筛里提到过)
            { // 说明i的质因数包括pj, 那么φ(i)里面包括 (1 - 1/pj), 一个数欧拉函数的大小和其质因数的次幂无关, 根据φ(N) = N * (1 - 1/p1) * (1 - 1/p2) * ... * (1 - 1/pk);
                sum += phi[i * primes[j]] = phi[i] * primes[j]; // pj * i 比 i 只多了一个pj而且pj还在i的质因数里面, 那么 φ(i*pj)只比φ(i)多一个pj 也就是 φ(i*pj) = φ(i) * pj
                break;
            }
            sum += phi[i * primes[j]] = phi[i] * (primes[j] - 1); // 和上面同理, 但是pj不是i的质因数, 所以φ(i) 不包含 (1 - 1/pj), φ(pj*i)需要加上这个 
        }
    }
    cout << sum + 1 << endl;
    
    return 0;
}

标签:...,p1,函数,int,pk,欧拉
From: https://www.cnblogs.com/blind5883/p/17841588.html

相关文章

  • 函数(3)函数原型和参数传递
    <1>函数原型(1)函数先后关系我们将自己定义的函数放在主函数main之前—————是因为:C的编译器自上而下顺序分析代码,这样在主函数中调用自定义函数才合理1.我们以一段代码为例#include<stdio.h>voidsum(intbegin,intend){inti;intsum=0;for(i=begin;i<=end;i++......
  • vue中遇到的函数执行顺序问题
    vue中遇到的函数执行顺序问题总结:vue中方法和方法间并未严格按照执行顺序执行的,可以使用async和await修饰符,使方法调用和执行是异步的。在vue中的方法调用顺序是依次进行的,方法体内部也是依次执行的,但是,两个方法体的执行顺序并不能严格控制,也就是说,并不一定是先执行完第一个方......
  • python 数据可视化:直方图、核密度估计图、箱线图、累积分布函数图
    本文使用数据来源自2023年数学建模国赛C题,以附件1、附件2数据为基础,通过excel的数据透视表等功能重新汇总了一份新的数据表,从中截取了一部分数据为例用于绘制图表。绘制的图表包括一维直方图、一维核密度估计图、二维直方图、二维核密度估计图、箱线图、累计分布函数图。 目录......
  • 入门c语言--基于c库函数strstr的实现
    #include<stdio.h>#include<assert.h>char*my_strstr(constchar*p1,constchar*p2){ assert(p1&&p2);//检查p1和p2是否为空指针//创建s1,s2来在p1,p2中进行移动,创建指针tmp来保存开始移动时的s1的位置 char*s1=NULL; char*s2=NULL; char*tmp=(char*)p1;//对p1......
  • C字符输入输出函数
    ......
  • Python中四大高阶函数,你认识几个
    1.匿名函数defname(a,b):returna+bf=lambdaa,b:a+bprint(f(15,15))2.map函数第一个参数接收一个函数名,第二个参数接收一个可迭代对象,利用map,lambda表达式将所有偶数元素加100deffun(a,b):returna+bret=map(fun,[1,2,3],[4,5,6])print(list(ret))3.sor......
  • 复变函数
    一、复变函数的基本知识由于在实数域中无法表示负数开根号问题,故将数系进行扩充,定义有\(i^{2}=-1\)1.复数的表示法\[代数形式:z=x+iy\qquad其中i为虚部单位\]\[指数形式:z=re^{i\theta}\qquad其中r为其幅值,\theta为幅角\]\[三角形式:根据欧拉公式,有:z=r(\cos\theta......
  • 前端歌谣-第贰拾贰课-函数参数默认值
    前言我是歌谣最好的种树是十年前其次是现在今天继续给大家带来的是this指向的讲解环境配置npminit-yyarnaddvite-D修改page.json配置端口{"name":"demo1","version":"1.0.0","description":"","main":"index.js",......
  • 函数(2)从函数中返回
    <1>从函数中返回值————————return:如果我们所定义的函数要返回一个结果,那么我们就需要用return将这个结果交给所调用的函数。(1)注意:返回类型我们以一段代码为例:intisprime(inti){intret=1;intk;for(k=2;k<i-1;k++){if(i%k==0){ret=0;break;}}returnret;......
  • mysql函数常见字符串函数
    1、BIT_LENGTH返回值为二进制的字符串str长度。--格式:BIT_LENGTH(str)selectBIT_LENGTH('abc'); 2、CONCAT返回结果为连接参数产生的字符串。--格式:concat(str1,str2,…)selectCONCAT('a','b','c')   3、ELT假设n等于1,用这个n去跟后一个数比较,如果n大......