POJ 1284

来源:互联网 发布:盘古数据股票 编辑:程序博客网 时间:2024/05/15 15:24

题意:求一个数的原根数;
设g是P的一个原根,那么 gi mod P 结果两两不同,
1 < g < P,0 < i < P(i最大取P-1)
就是说g是遍历出来的,次方数从小到大挨个判断,如果结果两两不同的话,就是一个原根。

我们使用欧拉定理,x的原根数恰好为x-1的欧拉函数的值

//欧拉函数int euler_phi(int n) {    int m = (int)sqrt(n + 0.5);    int ans = n;    for(int i = 2; i <= m; i++) if(n % i == 0) {        ans = ans / i * (i - 1);        while(n % i == 0) n /= i;    }     if(n > 1) ans = ans / n * (n - 1);    return ans;}

扩充
1、欧拉函数出了求原根的个数,还可以求约数的个数,由唯一分解定理可以把n分成

n=pa11pa22pa33pakk

n的任意正约数只能包含p1p2p3等素因数,对于n的某个素因子pi,它在所求约数中的指数可以是0,1,2,aiai+1种情况,而且不同的素因子之间相互独立,根据乘法原理,n的正约数的个数为
这里写图片描述
这个式子也是和欧拉函数等价的

2、小于n且与n互素的整数个数。
这里写图片描述
这个式子也是欧拉函数。

#include<iostream>#include<cmath>#define MAXN 65540using namespace std;int phi[MAXN];int euler_phi(int n) {    int m = (int)sqrt(n + 0.5);    int ans = n;    for(int i = 2; i <= m; i++) if(n % i == 0) {        ans = ans / i * (i - 1);        while(n % i == 0) n /= i;    }     if(n > 1) ans = ans / n * (n - 1);    return ans;}int main() {    int n;    while(cin >> n) {        cout << euler_phi(n-1) << endl;    }    return 0;}
原创粉丝点击