poj-1284 欧拉函数

欧拉函数

定义:对于一个正整数 n ,小于 n 且和 n 互质的正整数(包括 1)的个数,记作 φ(n) 

比如:n = 8 时,有 1,3,5,7 与它互质,所以 φ(8) = 4

函数计算公式:φ(n)=n*(1-1/p1)*(1-1/p2)*...*(1-1/pn) ,其中p1,p2,...,pn位n的质因子

易知,如果n为质数,一定有 φ(n) = n-1

函数的几个性质:

1、φ(1)=1

2、φ(pk)=pkpk1=(p1)pk1,其中p为质数

3、φ(mn)=φ(m)φ(n),其中gcd(m,n)=1

欧拉定理

   若n,a为正整数,且n,a互素(即\gcd(a,n)=1),则 a^{\varphi(n)} \equiv 1 \pmod n 。

   换种说法就是 a^ φ(n) % n 恒等于 1. 

      特别的,当n是质数的时候,上式就变成了a^{n - 1} \equiv 1 \pmod n ,它也叫费马小定理,但它是个单向定理,不能用这个同余证n是质数。

原根

gcd(a,m)=1时,定义a对模m的指数 Ord_m(a)  为使 a^d \equiv 1 \pmod{m} 成立的最小的正整数d。由欧拉定理知 Ord_m(a) 一定小于等于  \phi (m) ,

Ord_m (a) = \phi (m),则称a是模m的原根。

m的原根个数正好为φ(φ(m)) (在m是素数情况下进一步知原根的个数是φ(m-1) )

例:poj-1284  http://poj.org/problem?id=1284

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define N 1000005
int p[N];
void fun(){ //素数表
    int i, j, k;
    memset(p, 0, sizeof(p));
    p[1] = 1;
    for(i=2; i<=sqrt(N); i++){
        for(j=2; j<=N/i; j++){
            p[i*j] = 1;
        }
    }
}
int oula(int n){
    int i, j, r, a;
    r = n;
    a = n;
    for(i=2; i<=sqrt(n); i++){
        if(!p[i]){
            if(a%i==0){
                r = r/i * (i-1);
                while(a%i==0)
                    a /= i;
            }
        }
    }
    if(a>1)
        r = r/a*(a-1);
    return r;
}

int main(){
    int n;
    while(cin>>n){
       // cout<<oula(oula(n))<<endl; //一般情况
        cout<<oula(n-1)<<endl; //n为奇素数时
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值