求欧拉函数

/*3.欧拉函数
对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目
显然对素数n,phi(n)=n-1
通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。φ(1)=1(唯一和1互质的数就是1本身)
很简单,就不写代码什么的了
*/
降幂公式
当x≥ϕ(p)时,有ax≡axmodϕ(p)+ϕ(p)(mod p)
这部分可以参考“上帝与集合”
void init()
{
    for(int i = 1; i < maxn; i++)
        phi[i] = i;
    for(int i = 2; i < maxn; i++) {
        if(phi[i] == i) {
            for(int j = i; j < maxn; j += i) {
                phi[j] -= (phi[j] / i);
            }
        }
    }
}
//直接求解欧拉函数
//根号n求欧拉函数 注意是 i*i<=x
LL euler(LL n)
{
    //返回euler(n)
    LL res = n, a = n;
    for(LL i = 2; i * i <= a; i++) {
        if(a % i == 0) {
            res = res / i * (i - 1); //先进行除法是为了防止中间数据的溢出
            while(a % i == 0) a /= i;
        }
    }
    if(a > 1) res = res / a * (a - 1);
    return res;
}
//O(n)求欧拉函数
int prime[N + 5], phi[N + 5]; bool noprime[N + 5];
//1. phi(p)=p-1   因为质数p除了1以外的因数只有p,故1至p的整数只有p与p不互质
//2. 如果i mod p = 0, 那么phi(i * p)=p * phi(i)
//3.若i mod p ≠0,  那么phi(i * p)=phi(i) * (p-1)
void euler(){
    int size = 0;
    phi[1] = 1;
    for(int i = 2; i <= N; i++) {
        if(!noprime[i]) {
            prime[++size] = i;
            phi[i] = i - 1;
        }
        for(int j = 1; j <= size && i * prime[j] <= N - 5; j++) {
            noprime[i * prime[j]] = 1;
            if(i % prime[j] == 0) {
                phi[i * prime[j]] = prime[j] * phi[i]; //!!
                break;
            }
            phi[i * prime[j]] = phi[i] * (prime[j] - 1);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39599067/article/details/81170021