✨博主:命运之光
✨专栏:算法基础学习
目录
✨欧拉函数
🍓求欧拉函数 :
🍓筛法求欧拉函数 :
✨快速幂
✨扩展欧几里得算法
✨中国剩余定理
前言:算法学习笔记记录日常分享,需要的看哈O(∩_∩)O,感谢大家的支持!
✨欧拉函数
在C语言中,可以使用算法来计算欧拉函数(Euler's Totient Function)。欧拉函数,也被称为φ函数,用于计算小于或等于给定数字n的正整数中与n互质的数的个数。
🍓以下是一个用C语言编写的计算欧拉函数的示例代码:
#include <stdio.h>
int gcd(int a, int b) {
if (b == 0)
return a;
return gcd(b, a % b);
}
int eulerTotient(int n) {
int count = 0;
for (int i = 1; i <= n; i++) {
if (gcd(n, i) == 1) {
count++;
}
}
return count;
}
int main() {
int n;
printf("Enter a number: ");
scanf("%d", &n);
int result = eulerTotient(n);
printf("Euler's Totient Function of %d is %d\n", n, result);
return 0;
}
在上述代码中,gcd函数用于计算两个数的最大公约数。eulerTotient函数遍历从1到n的所有数字,检查它们是否与n互质(即它们的最大公约数为1),并统计互质的数字的个数。最后,程序输出计算得到的欧拉函数值。可以运行上述代码,输入一个正整数,程序将计算并输出该数的欧拉函数值。
表示:
定义:1~n中与n互质的数的个数
🍓求欧拉函数 :
int phi(int x)
{
int res = x;
for (int i = 2; i <= x / i; 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 primes[N], cnt; // primes[]存储所有素数,cnt存储每个素数的下标
int euler[N]; // 存储每个数的欧拉函数
bool st[N]; // st[x]存储x是否被筛掉
void get_eulers(int n)
{
euler[1] = 1;
for (int i = 2; i <= n; i ++ )
{
if (!st[i])
{
primes[cnt ++ ] = i;
euler[i] = i - 1;
}
for (int j = 0; primes[j] <= n / i; j ++ )
{
int t = primes[j] * i;
st[t] = true;
if (i % primes[j] == 0)
{
euler[t] = euler[i] * primes[j];
break;
}
euler[t] = euler[i] * (primes[j] - 1);
}
}
}
✨快速幂
在C语言中,可以使用快速幂算法(Fast Exponentiation)来高效计算幂运算。快速幂算法通过将指数分解为二进制形式,从而减少了乘法和幂运算的次数,从而提高了计算效率。
🍓以下是一个用C语言编写的快速幂算法的示例代码:
#include <stdio.h>
long long fastExponentiation(int base, int exponent) {
long long result = 1;
while (exponent > 0) {
if (exponent % 2 == 1) {
result *= base;
}
base *= base;
exponent /= 2;
}
return result;
}
int main() {
int base, exponent;
printf("Enter the base: ");
scanf("%d", &base);
printf("Enter the exponent: ");
scanf("%d", &exponent);
long long result = fastExponentiation(base, exponent);
printf("%d raised to the power of %d is %lld\n", base, exponent, result);
return 0;
}
在上述代码中,fastExponentiation函数使用了迭代的方式来计算幂运算。它首先将结果初始化为1,并进入循环。在每次循环中,它检查指数的最低位(通过取模2),如果最低位为1,则将结果乘以当前的基数。然后,将基数平方,并将指数除以2。重复这个过程,直到指数变为0,然后返回计算得到的结果。可以运行上述代码,输入一个基数和指数,程序将计算并输出幂运算的结果。请注意,由于幂运算的结果可能非常大,因此将结果的数据类型设置为long long来处理大整数。
✨扩展欧几里得算法
在C语言中,可以使用扩展欧几里得算法(Extended Euclidean Algorithm)来求解两个整数的最大公约数(最大公因数),并且同时计算出满足贝祖等式(Bézout's identity)的两个整数系数。
🍓以下是一个用C语言编写的扩展欧几里得算法的示例代码:
#include <stdio.h>
int extendedEuclidean(int a, int b, int *x, int *y) {
// 初始情况
if (a == 0) {
*x = 0;
*y = 1;
return b;
}
int x1, y1;
int gcd = extendedEuclidean(b % a, a, &x1, &y1);
// 更新x和y
*x = y1 - (b / a) * x1;
*y = x1;
return gcd;
}
int main() {
int a, b;
printf("Enter two numbers: ");
scanf("%d %d", &a, &b);
int x, y;
int gcd = extendedEuclidean(a, b, &x, &y);
printf("GCD: %d\n", gcd);
printf("Coefficients (x, y): (%d, %d)\n", x, y);
return 0;
}
在上述代码中,extendedEuclidean函数使用递归的方式来实现扩展欧几里得算法。它将两个整数a和b作为输入,并返回它们的最大公约数。同时,它通过指针参数x和y返回满足贝祖等式的两个整数系数。
在函数中,我们首先处理初始情况,当a为0时,最大公约数为b,系数x为0,系数y为1。否则,我们递归调用函数,将b mod a和a作为新的输入,并获取递归返回的最大公约数、系数x1和系数y1。
然后,我们使用贝祖等式的推导来更新系数x和系数y:x = y1 - (b / a) * x1,y = x1。
最后,我们在main函数中接受用户输入的两个整数a和b,并调用extendedEuclidean函数来计算最大公约数和系数。然后,我们输出最大公约数和系数的结果。
你可以运行上述代码,输入两个整数,程序将计算并输出最大公约数和满足贝祖等式的系数。
扩展欧几里得算法 :
✨中国剩余定理
在C语言中,可以使用中国剩余定理(Chinese Remainder Theorem)来求解一组同余方程组的解。中国剩余定理是一种在模数互质的情况下求解同余方程组的有效方法。
🍓以下是一个用C语言编写的中国剩余定理算法的示例代码:
#include <stdio.h>
int extendedEuclidean(int a, int b, int *x, int *y) {
// 初始情况
if (a == 0) {
*x = 0;
*y = 1;
return b;
}
int x1, y1;
int gcd = extendedEuclidean(b % a, a, &x1, &y1);
// 更新x和y
*x = y1 - (b / a) * x1;
*y = x1;
return gcd;
}
int modInverse(int a, int m) {
int x, y;
int gcd = extendedEuclidean(a, m, &x, &y);
if (gcd != 1) {
printf("Inverse doesn't exist\n");
return -1;
}
int result = (x % m + m) % m;
return result;
}
int chineseRemainder(int num[], int rem[], int n) {
int prod = 1;
for (int i = 0; i < n; i++) {
prod *= num[i];
}
int result = 0;
for (int i = 0; i < n; i++) {
int pp = prod / num[i];
int inv = modInverse(pp, num[i]);
result += rem[i] * pp * inv;
}
result %= prod;
return result;
}
int main() {
int num[10], rem[10], n;
printf("Enter the number of equations: ");
scanf("%d", &n);
printf("Enter the values of equations (num and rem):\n");
for (int i = 0; i < n; i++) {
scanf("%d %d", &num[i], &rem[i]);
}
int result = chineseRemainder(num, rem, n);
printf("Solution: %d\n", result);
return 0;
}
在上述代码中,我们定义了三个函数:extendedEuclidean用于计算最大公约数和系数,modInverse用于计算模反元素(模逆元),chineseRemainder用于求解同余方程组。
extendedEuclidean和modInverse函数的实现与之前提到的扩展欧几里得算法的示例代码中的函数相同。
chineseRemainder函数首先计算所有模数的乘积,然后使用循环计算每个同余方程的乘积、模逆元和余数,最后将所有结果求和。最终,通过对乘积取模得到最小非负整数解。
在main函数中,我们首先接受用户输入的同余方程个数和每个方程的模数和余数。然后,调用chineseRemainder函数来计算同余方程组的解,并输出值。