欧拉函数 最大素因数 素数判断 素数表

本文探讨了数论中的欧拉函数,包括如何计算小于等于n的与n互质的数的数目,求解最大素因数的方法,以及如何快速判断一个数是否为素数。在某些情况下,预计算最大值或素数表可以避免超时。欧拉函数可通过素数幂分解公式计算,而素数判断通常涉及对平方根以内数字的检查。
摘要由CSDN通过智能技术生成
  1. 求欧拉函数(小于等于n的数中与n互质的数的数目)
  2. 求最大素因数
  3. 打素数表
  4. 判断一个数是否是素数
  5. 在一些题目中,需要先提前暴力出最大值,否则会超时。
  6. 1的欧拉函数值是1,但是看题目说明,有些题目认为小于等于,有些只有小于
  7. 1与任何数互质
  8. 不与n互质的数不一定是n的约数
  9. 最后的n>1是为了处理当n是两个素数相乘或者是一个素数的情况。

欧拉函数:
数论中,对于正整数n,欧拉函数是小于等于n的数中与n互质的数的数目。 原理:素数幂分解后,f(n) = n*(1-1/p1)…..(1-1/pk) (容斥原理变形) 单独求欧拉的函数实现过程恰好相反。 最小的质数是2,1不是质数。 用一变量保存i,最后一个i即最大素因数。

//求欧拉函数
long long euler_phi(long long n) {
    long long m = sqrt(n);
    long long ans = n;
    for(int i = 2; i <= m; i++) {
        if(n%i == 0) { //用变量保存i即最大的素因数
            ans = ans / i * (i-1);
            while(n%i == 0)
                n /= i;
        }
        if(n == 1)  break;
    }
    if(n>1)
        ans = ans / n * (n-1);
    return ans;
}
//求n以内的欧拉函数值
//每一个素数的倍数都除去这个素数的影响。
const int maxn = 10000001;
int phi[maxn+5];
void phi_table(){
    memset(phi,0,sizeof(phi));
    phi[1] = 1;//数对(1,1)
    for(int i = 2; i <= maxn; i++){
        if(phi[i] == 0){
            for(int j = i; j <= maxn; j += i){
                if(phi[j] == 0)
                    phi[j] = j;
                phi[j] = phi[j] / i * (i-1);
            }
        }
    }
}

求n!的欧拉函数对mod的余数。

const int N = 10000000;
bool primeTable[N+5];

void make_primeTable(){
    fill(primeTable,primeTable+N,1);
    primeTable[0] = false;
    primeTable[1] = false;

    int maxed = sqrt(N);
    for(int i = 2; i <= maxed; ++i){
        if(primeTable[i]){
            for(int j = i*i; j <= N; j += i)
                primeTable[j] = false;
        }
    }
}
const int maxn = 10000000;
const int mod = 100000007;
long long phi[maxn+5];
void phi_table(){
    memset(phi,0,sizeof(phi));
    phi[1] = phi[2] = 1;
    for(int i = 3; i <= maxn; ++i){
        if(primeTable[i] == true)
            phi[i] = (i-1)*phi[i-1]%mod;
        else
            phi[i] = i*phi[i-1]%mod;
    }
}

题目中数据量大(大于sqrt(n))往往需要先打表

//生成素数表
//线性复杂度,10^8需要101ms左右
//the prime's size = N/lnN; more than 10^5  can use 10
const int maxn = 100000000;
bool isPrime[maxn+5];
vector<int> prime;

void cac_prime(){
    fill(isPrime, isPrime+maxn, true);
    isPrime[0] = isPrime[1] = false;

    for(int i = 2; i <= maxn; ++i) {
        if(isPrime[i])
            prime.push_back(i);
        for(int j = 0; i*prime[j] < maxn; ++j){
            isPrime[i*prime[j]] = false;
            if(i%prime[j] == 0)
                break;
        }
    }
}

素数判断

bool isPrime(int x){
    int s = sqrt(x);
    if(x == 0 || x == 1)  return false;
    if((x%2)==0 && x != 2)  return false;
    for(int i = 3; i <= s; i+=2)
        if(!(x%i))  return false;
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值