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)为欧拉函数)
浙公网安备 33010602011771号