今日学习了基本数论内容,LCM,GCD以及筛素数
GCD-最大公约数
int gcd(int a,int b){//迭代法
while(b){//要保证a大于b
int t=a%b;
a=b;
b=t;
}
return a
}//辗转相除法int gcd(int a,int b){//递归法return b?gcd(b,a%b):a;//一定要保证a大于b
}
LCM-最小公倍数
可以套公式LCM=a*b/gcd(a,b)
分解质因数
void divide(int x){for(int i=2;i<=x/i;i++){//时间复杂度是根号n到lognif(x%i==0){//i为x的因数,因为从小到大枚举int s=0;while(x%i==0){x/=i;s++;}printf("%d %d\n",i,s);}}if(x>1) printf("%d %d\n",x,1);puts("");
}
因为x每次会被最小满足条件的i整除,所以满足条件的i一定是质数
接着用while循环算出i对应的幂s即可
筛素数
埃式筛法就是从质数开始枚举,并把每个质数的整数倍的合数剔除出列表
bool st[N]; // st[x]存储x是否被筛掉
int cnt;
void get_primes(int n){//埃式筛法for(int i=2;i<=n;i++){//时间复杂度为nloglogn,约等于O(n)if(!st[i]){cnt++;for(int j=i+i;j<=n;j+=i){//枚举i的倍数,一定是合数st[j]=true;}}}
}
线性筛法
int primes[N], cnt; // primes[]存储所有素数
bool st[N]; // st[x]存储x是否被筛掉
//yxc
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;}}
}