您的位置:首页 > 汽车 > 时评 > 室内设计联盟官方app_西双版纳傣族自治州天气预报15天_培训行业seo整站优化_长春做网络优化的公司

室内设计联盟官方app_西双版纳傣族自治州天气预报15天_培训行业seo整站优化_长春做网络优化的公司

2025/9/9 14:41:50 来源:https://blog.csdn.net/2401_86517033/article/details/145588726  浏览:    关键词:室内设计联盟官方app_西双版纳傣族自治州天气预报15天_培训行业seo整站优化_长春做网络优化的公司
室内设计联盟官方app_西双版纳傣族自治州天气预报15天_培训行业seo整站优化_长春做网络优化的公司

未完待续 

一、质数(素数) 

1.1质数的判定(试除法)

注:

(1)整除的性质:d|n,n/d|n  成对出现,n为d的整数倍

bool is_prime(int x)
{if (x < 2) return false;for (int i = 2; i <= x / i; i ++ )if (x % i == 0)return false;return true;
}

1.2分解质因数(试除法)

注:n中最多只包含一个大于sqrt(n)的质因子

void divide(int x)
{//枚举到sqrt(n) for (int i = 2; i <= x / i; i ++ )if (x % i == 0){int s = 0;//枚举i的次数 while (x % i == 0) x /= i, s ++ ;cout << i << ' ' << s << endl;}//n中最多只包含一个大于sqrt(n)的质因子 if (x > 1) cout << x << ' ' << 1 << endl;cout << endl;
}

1.3朴素筛法求质数(埃式筛法)

时间复杂度:O(nloglogn)

 

int primes[N], cnt;     // primes[]存储所有素数
bool st[N]; 
//假设 st[]数组初始值均为 false,表示还没有任何数字被标记为合数。
// st[x]为true表示x是合数 void get_primes(int n)
{for (int i = 2; i <= n; i ++ ){if (st[i]) continue;//跳过以下语句 primes[cnt ++ ] = i;for (int j = i + i; j <= n; j += i)st[j] = true;}
}

 1.4线性筛法求质数

n只会被最小质因子筛掉

在欧拉筛法(Euler's Sieve)中,关键点之一是确保每个合数只会被其最小质因子筛掉一次。如果继续遍历更大的素数而不跳出循环,可能会导致同一个合数被多次标记为合数,从而影响算法的效率。

int primes[N], cnt;     // primes[]存储所有素数
bool st[N];         // st[x]存储x是否被筛掉void get_primes(int n)
{for (int i = 2; i <= n; i ++ ){if (!st[i]) primes[cnt ++ ] = i;//从小到大枚举质数 for (int j = 0; primes[j] <= n / i; j ++ ){st[primes[j] * i] = true;if (i % primes[j] == 0) break;//primes[j]一定是i的最小质因子 }}
}

 二、约数

约数(或称为因数)是指能够整除某个整数的整数。具体来说,如果整数 a能够被整数 b 整除(即 a/b的结果是整数且没有余数),那么 b 就是 a 的一个约数。

2.1试除法求所有约数

vector<int> get_divisors(int x)
{vector<int> res;//存约数 for (int i = 1; i <= x / i; i ++ )if (x % i == 0){res.push_back(i);//x有可能是i的平方,两个约数一样 if (i != x / i) res.push_back(x / i);}//给约数排序 sort(res.begin(), res.end());return res;
}

  2.2约数个数和约数之和  

 如果 N = p1^c1 * p2^c2 * ... *pk^ck
约数个数: (c1 + 1) * (c2 + 1) * ... * (ck + 1)
约数之和: (p1^0 + p1^1 + ... + p1^c1) * ... * (pk^0 + pk^1 + ... + pk^ck)

2.3欧几里得算法 

辗转相除法计算两个整数的最大公约数GCD

int gcd(int a, int b)
{return b ? gcd(b, a % b) : a;
}

和最小公倍数LCM之间的关系

GCD(a,b)*LCM(a,b)=a*b

三、欧拉函数

 

四、快速幂

原始版

#include<bits/stdc++.h>
using namespace std; long long quick_pow(long long a,long long b){//计算a^b次方long long res = 1;//用res保存答案//当b变成0后就可以停止循环了while(b){if(b & 1) res*=a;//如果b当前二进制为1就要乘上这个数b>>=1; //将b末尾的二进制数删掉a*=a; // 将a乘以自己进行翻倍(平方) //比如,开始a==5,接下来a = 5^2,a=5^4,a=5^8,a=5^16....//通过遍历每个在范围内的2的次方数来更新a}return res;
}
int main()
{long long a,b;cin>>a>>b;cout<<quick_pow(a,b);
}

快速地求出a^k mol p的结果

前置知识 (a *b *c *d )%p = (((a *b)%p *c)%p *d)%p

即每次乘以下个数前可以先取模,这样最后答案不变

答案不变真的好抽象、 

LL quick_pow(LL a, LL b, LL p){ //LL是long long 的缩写//p是要对取模的数字LL ans = 1;while(b){if(b & 1)ans =(ans*a)%p;b >>= 1;a = (a*a) % p;}return ans;}

Example:快速幂求逆元 

同余

乘法逆元定义

 acwing版本:

 

 

五、扩展欧几里得算法

 

 

exgcd这个函数里面x和y这两个参数是传引用(pass by reference)进来的,事实上这两个参数也是函数的输出值。根据我们前面推导的式子,每次更新我们想要让 x = y1, 然后 y = x1 - 【a / b】 * y1,所以在调用递归的时候,我们直接把x传成y,然后y传成x,这样下来就相当于x = y1, y = x1,之后我们只需要再把 y -= 【a / b】 * y1 就可以了 

// 求x, y,使得ax + by = gcd(a, b)
int exgcd(int a, int b, int &x, int &y)
{if (!b){x = 1; y = 0;return a;}int d = exgcd(b, a % b, y, x);y -= (a/b) * x;return d;
}

x,y系数的所有解 

 

Example1 

 Example2

 

 

// 计算 a 在模 m 下的乘法逆元
int mod_inverse(int a, int m) {int x, y;int gcd = exgcd(a, m, x, y);if (gcd != 1)//a与m不互质,逆元不存在 return -1; else {// x 可能为负数,需要转换为正数int result = (x % m + m) % m;return result;}
}

 

 Example3

 

取模运算原因

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com