![在这里插入图片描述](https://img-blog.csdnimg.cn/fd6b19c05782490fbc82948837b60c37.jpg?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAV1RjcmF6eSAu,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
求约数
试除法求约数
vector<int> v;
scanf("%d", &n); //试除法求n的约数
for (int i = 1; i * i <= n; i++)
{
if (n % i == 0)
v.push_back(i);
if (n / i != i)
v.push_back(n / i);
}
sort(v.begin(), v.end());
for (int i = 0; i < v.size(); i++)
printf("%d ", v[i]);
试除法的推论:一个整数n的约数个数上界为2 *是√n
倍数法求约数
scanf("%d", &n); //倍数法求1~n的约数
vector<int> v[n + 1]; //不可开成v[n]
for (int i = 1; i <= n; i++)
{ //反过来考虑
for (int j = 1; j <= n / i; j++)
v[i * j].push_back(i);
}
for (int i = 1; i <= n; i++)
{
printf("%d---", i);
for (int j = 0; j < v[i].size(); j++)
printf("%d ", v[i][j]);
puts("");
}
倍数法的推论:1 ~n的每个数的约数个数的总和大约为nlogn
最大公约数
欧几里得算法
ll gcd(ll x, ll y) { return y == 0 ? x : gcd(y, x % y); }
互质与欧拉函数
- 1.若i为素数,则phi[i]=i-1
- 2.若i为素数,j%i==0,phi[ij]=iphi[j]【性质4】
- 3.若i,j互质,phi[i*j]=phi[i]*phi[j]【积性函数】【性质5】
根据定义求欧拉函数
int eular(int n)
{
int res = n;
for (int i = 1; prime[i] * prime[i] <= n; i++)
{
if (n % prime[i] == 0)
res = res / prime[i] * (prime[i] - 1);
while (n % prime[i] == 0)
n /= prime[i];
}
if (n > 1)
res = res / n * (n - 1);
return res;
}
利用欧拉筛求解欧拉函数
void eular() //欧拉筛
{
ll cnt = 0;
memset(isprime, 1, sizeof(isprime));
isprime[0] = isprime[1] = 0;
for (ll i = 2; i <= N; i++)
{
if (isprime[i])
{
prime[cnt++] = i;
phi[i] = i - 1; //特性1
}
for (ll j = 0; j < cnt && i * prime[j] < N; j++)
{
isprime[i * prime[j]] = 0; //注意[]里面是i*prime[j]
if (i % prime[j] == 0) //注意是==0
{
phi[i * prime[j]] = prime[j] * phi[i]; //特性2
break;
}
else
phi[i * prime[j]] = phi[i] * (prime[j] - 1); //特性3,phi[prime[j]]=prime[j]-1
}
}
}