跳转至

POJ Numeric

1284. Primitive Roots

给一个奇质数,求它的原根(primitive root)个数,原根定义是,如果整数a是p的原根,说明a^1, a^2 ... a^(p-1) mod p的结果正好是从1到p-1都有

这里用到的是一个定理,如果一个整数有原根,那么它的原根个数是\phi(\phi(n)),质数欧拉函数值是质数减1,所以直接求n-1的欧拉函数值即可,这里\phi(1)=0

证明是否存在原根的方法如link,可见奇素数一定有原根

这里n的范围是小于65536,所以直接先筛出所有欧拉函数的值,然后返回即可

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> eu(65536, 0);
    for (int i = 2; i < eu.size(); i++) {
        if (eu[i] == 0) {
            for (int j = i; j < eu.size(); j += i) {
                if (eu[j] == 0) eu[j] = j;
                eu[j] -= eu[j] / i;
            }
        }
    }
    int n;
    while (cin >> n) {
        cout << eu[n-1] << '\n';
        if (cin.eof()) break;
    }
}

2407. Relatives

给一个整数n<10^9,求小于等于n且和n互质的数的个数,输入以0结束

因为范围过大,不能全部求1到n的欧拉函数,所以对每个数单独求解

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n;
    while (cin >> n) {
        if (n == 0) break;
        else if (n == 1) {
            cout << "1\n";
            continue;
        }
        int phi = n;
        for (int i = 2; i * i <= n; i++) {
            if (n % i == 0) phi -= phi / i;
            while (n % i == 0) n /= i;
        }
        if (n > 1) phi -= phi / n;
        cout << phi << '\n';
    }
}