Xuzhou Winter Camp 7(数论专题)

A 欧拉函数裸题

#include<iostream>
#define ll long long
using namespace std;
ll phi(ll x)
{   
    ll res = x;
    for(ll i = 2; i * i <= x; i ++)
    {
        if(x % i == 0)
        {
            res = res / i * (i - 1);
            while(x % i == 0)
                x /= i;
        }
    }
    if(x > 1)
        res = res / x * (x - 1);
    return res;
}
int main()
{
    int n;
    while(cin >> n && n)
    {
        cout << phi(n) << endl;
    }
       return 0;
}

另附 递推求法:

void init()
{
    int i, j;
    memset(phi, 0, sizeof(phi));
    phi[1] = 1;
    for(int i = 2; i < SIZE; i++) if(!phi[i])
    {
        for(j = i; j < SIZE; j+=i)
        {
            if(!phi[j]) phi[j] = j;
            phi[j] = phi[j] / i * (i-1);
        }
    }

}

B题 求 ∑gcd(i, N).
题目分析:∑gcd(i, N) = ∑(d|N) d*phi[N/d]
phi[N / d]就是1 - N中与N最大公约数为d的个数,因为phi[n]表示小于等于n且与n互质的数的个数,那么n除去d这个因子后所求的欧拉函数值正是乘了d以后与N最大公约数为d的数的个数所以直接用公式即可。

#include <cstdio>
#define ll long long
 
ll phi(ll x)
{   
    ll res = x;
    for(ll i = 2; i * i <= x; i ++)
    {
        if(x % i == 0)
        {
            res = res / i * (i - 1);
            while(x % i == 0)
                x /= i;
        }
    }
    if(x > 1)
        res = res / x * (x - 1);
    return res;
}
 
int main()
{
    ll n;
    while(scanf("%lld", &n) != EOF)
    {
        ll ans = 0;
        for(ll i = 1; i * i <= n; i++)
        {   
            if(n % i == 0)
            {
                ans += i * phi(n / i);
                if(i * i != n)
                    ans += n / i * phi(i);
            }
        }
        printf("%lld\n", ans);
    }
}

C题:使 { (xI mod p) | 1<=i<=p-1} = { 1, …, p-1 }.
欧拉函数+原根:
由费马小定理可知 如果a于p互质 则有a^(p-1)≡1(mod p)
对于任意的a是不是一定要到p-1次幂才会出现上述情况呢?
显然不是,当第一次出现a^k≡1(mod p)时, 记为ep(a)=k 当k=(p-1)时,称a是p的原根
每个素数恰好有f(p-1)个原根(f(x)为欧拉函数)

定理:对于奇素数m, 原根个数为phi(phi(m)), 由于phi(m)=m-1, 所以为phi(m-1)。
posted @ 2019-02-11 23:25  Mr.doublerun  阅读(29)  评论(0)    收藏  举报