数论8——欧拉函数

欧拉函数,用φ(n)表示

欧拉函数是求小于等于n的数中与n互质的数的数目

辣么,怎么求哩?~(~o ̄▽ ̄)~o

可以先在1到n-1中找到与n不互质的数,然后把他们减掉

比如φ(12)

把12质因数分解,12=2*2*3,其实就是得到了2和3两个质因数

然后把2的倍数和3的倍数都删掉

2的倍数:2,4,6,8,10,12

3的倍数:3,6,9,12

本来想直接用12 - 12/2 - 12/3

但是6和12重复减了

所以还要把即是2的倍数又是3的倍数的数加回来 (>﹏<)

所以这样写12 - 12/2 - 12/3 + 12/(2*3)

这叫什么,这叫容斥啊,容斥定理听过吧

比如φ(30),30 = 2*3*5

所以φ(30) = 30 - 30/2 - 30/3 - 30/5 + 30/(2*3) + 30/(2*5) + 30/(3*5) - 30/(2*3*5)

但是容斥写起来好麻烦( ̄. ̄)

有一种简单的方法

φ(12)   =   12*(1 - 1/2)*(1 - 1/3)                 =   12*(1 - 1/2 - 1/3 + 1/6)

φ(30)   =   30*(1 - 1/2)*(1 - 1/3)*(1 - 1/5)   =   30*(1 - 1/2 - 1/3 - 1/5 + 1/6 + 1/10 + 1/15 - 1/30)

你看( ????? ),拆开后发现它帮你自动帮你容斥好

所以φ(30)的计算方法就是先找30的质因数

分别是2,3,5

然后用30* 1/2 * 2/3 * 4/5就搞定了

顺便一提,phi(1) = 1

代码如下:

//欧拉函数
int phi(int x){
    int ans = x;
    for(int i = 2; i*i <= x; i++){
        if(x % i == 0){
            ans = ans / i * (i-1);
            while(x % i == 0) x /= i;
        }
    }
    if(x > 1) ans = ans / x * (x-1);
    return ans;
}

  

(phi就是φ的读音)

机智的代码,机智的我(??`ω′?)

这个的复杂度是O(√n),如果要你求n个数的欧拉函数,复杂度是O(n√n),这也太慢了

有更快的方法

跟埃筛素数差不多

#include<cstdio>
const int N = 100000 + 5;
int phi[N];
void Euler(){
    phi[1] = 1;
    for(int i = 2; i < N; i ++){
        if(!phi[i]){
            for(int j = i; j < N; j += i){
                if(!phi[j]) phi[j] = j;
                phi[j] = phi[j] / i * (i-1);
            }
        }
    }
}
int main(){
    Euler();
}

(Euler就是欧拉)

另一种,比上面更快的方法

需要用到如下性质

p为质数

1. phi(p)=p-1   因为质数p除了1以外的因数只有p,故1至p的整数只有p与p不互质

2. 如果i mod p = 0, 那么 phi(i * p)=phi(i) * p         (我不会证明)

3.若i mod p ≠0,  那么 phi( i * p )=phi(i) * ( p-1 )   (我不会证明)

(所以我说我会证明都是骗人的╮( ̄▽ ̄)╭)

代码如下:

#include<cstdio>
using namespace std;
const int N = 1e6+10 ;
int phi[N], prime[N];
int tot;//tot计数,表示prime[N]中有多少质数
void Euler(){
    phi[1] = 1;
    for(int i = 2; i < N; i ++){
        if(!phi[i]){
            phi[i] = i-1;
            prime[tot ++] = i;
        }
        for(int j = 0; j < tot && 1ll*i*prime[j] < N; j ++){
            if(i % prime[j]) phi[i * prime[j]] = phi[i] * (prime[j]-1);
            else{
                phi[i * prime[j] ] = phi[i] * prime[j];
                break;
            }
        }
    }
}

int main(){
    Euler();
}

最后说下

a^b % p  不等价  (a%p)^(b%p) % p

因为

a^φ(p) ≡ 1 (mod p)

所以

a^b % p  =  (a%p)^(b%φ(p)) % p

(欧拉函数前提是a和p互质)

如果p是质数

直接用这个公式

机智的代码,机智的我(??`ω′?)

///////////////////////////////////////////////

2016年7月23号

我的天哪,我又发现了一个新公式,貌似可以摆脱a和p互质的束缚,让我们来命名为:超欧拉取模进化公式

这是历史性的一刻,妈妈再也不用为a和p不互质而担心了= =

时间: 2024-10-07 06:32:17

数论8——欧拉函数的相关文章

hihoCoder 1298 : 数论五&#183;欧拉函数

#1298 : 数论五·欧拉函数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho有时候会用密码写信来互相联系,他们用了一个很大的数当做密钥.小Hi和小Ho约定了一个区间[L,R],每次小Hi和小Ho会选择其中的一个数作为密钥. 小Hi:小Ho,这次我们选[L,R]中的一个数K. 小Ho:恩,小Hi,这个K是多少啊? 小Hi:这个K嘛,不如这一次小Ho你自己想办法算一算怎么样?我这次选择的K满足这样一个条件: 假设φ(n)表示1..n-1中与n互质的数

数论五&#183;欧拉函数

#1298 : 数论五·欧拉函数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho有时候会用密码写信来互相联系,他们用了一个很大的数当做密钥.小Hi和小Ho约定了一个区间[L,R],每次小Hi和小Ho会选择其中的一个数作为密钥. 小Hi:小Ho,这次我们选[L,R]中的一个数K. 小Ho:恩,小Hi,这个K是多少啊? 小Hi:这个K嘛,不如这一次小Ho你自己想办法算一算怎么样?我这次选择的K满足这样一个条件: 假设φ(n)表示1..n-1中与n互质的数

hihoCoder 数论五&#183;欧拉函数

题目1 : 数论五·欧拉函数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho有时候会用密码写信来互相联系,他们用了一个很大的数当做密钥.小Hi和小Ho约定了一个区间[L,R],每次小Hi和小Ho会选择其中的一个数作为密钥. 小Hi:小Ho,这次我们选[L,R]中的一个数K. 小Ho:恩,小Hi,这个K是多少啊? 小Hi:这个K嘛,不如这一次小Ho你自己想办法算一算怎么样?我这次选择的K满足这样一个条件: 假设φ(n)表示1..n-1中与n互质的数的个

「POJ3696」The Luckiest number【数论,欧拉函数】

# 题解 一道数论欧拉函数和欧拉定理的入门好题. 虽然我提交的时候POJ炸掉了,但是在hdu里面A掉了,应该是一样的吧. 首先我们需要求的这个数一定可以表示成\(\frac{(10^x-1)}{9}\times 8\). 那么可以列出一个下面的方程 \[\frac{(10^x-1)}{9}\times 8=L\times k\] 设\(d=gcd(9L,8)=gcd(L,8)\) \[\frac89(10^x-1)=Lk\] \[\frac{8(10^x-1)}d=\frac{9Lk}{d}\]

【SGU】SGU每日练1&#183;Coprimes【数论】欧拉函数

先介绍欧拉函数及其相关定理吧: 1.欧拉函数:对于任意一个数X,将其分解质因数为X=(P1^b1)*(P2^b2)*(P3^b3)...... 则小于X的与X互质的数的个数N为N = X * (1 - 1 / p1) * (1 - 1 / p2)....... 显然对于质数p,Euler(p) = p - 1: 2.一个数的所有质因子之和是euler(n)*n/2: 3.a^Euler(n) % n = 1,这里可以用模运算来证明: 具体实现: 1.先筛素数 2.从2开始遍历素数,能整除则乘,然

[BZOJ2818] Gcd (数论,欧拉函数,线性筛)

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2818 必须用线性筛. 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn = 10001001; 5 LL phi[maxn], sum[maxn], n; 6 bool isprime[maxn]; 7 LL prime[maxn]; 8 int tot;

【数论】欧拉函数

欧拉函数φ      欧拉定理是用来阐述素数模下,指数同余的性质.      欧拉定理:对于正整数N,代表小于等于N的与N互质的数的个数,记作φ(N)      例如φ(8)=4,因为与8互质且小于等于8的正整数有4个,它们是:1,3,5,7     欧拉定理还有几个引理,具体如下:     ①:如果n为某一个素数p,则φ(p)=p-1;     ①很好证明:因为素数p的质因数只有1和它本身,p和p不为互质,所以φ(p)=p-1:     ②:如果n为某一个素数p的幂次,那么φ(p^a)=(p-

CF1114F Please, another Queries on Array?(线段树,数论,欧拉函数,状态压缩)

这题我在考场上也是想出了正解的……但是没调出来. 题目链接:CF原网 题目大意:给一个长度为 $n$ 的序列 $a$,$q$ 个操作:区间乘 $x$,求区间乘积的欧拉函数模 $10^9+7$ 的值. $1\le n\le 4\times 10^5,1\le q\le 2\times 10^5,1\le a_i,x\le 300$.时限 5.5s,空限 256MB. 明显线段树. 有一个想法是维护区间积的欧拉函数,但是这样时间复杂度和代码复杂度都很高…… 我的做法是维护区间积.而欧拉函数,就是看看

hdoj 1286 找新朋友 【数论之欧拉函数】

找新朋友 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7912    Accepted Submission(s): 4157 Problem Description 新年快到了,"猪头帮协会"准备搞一个聚会,已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大