唯一分解定理:任一大于1的自然数,要么本身是质数,要么可以分解为几个质数之积,且这种分解是唯一的。 即 对于任一个正整数X(除了1)都有这样一个式子: p是素因子,a是素因子的个数
素数判断,根号n快速判断,我就不多说了
素数筛法:
朴素筛法 ( 复杂度nlog(n) ):
int prim[maxn],cnt = 0; //存放素数并计数
bool flag[maxn]; // 0为质数 1非质数
for(int i = 2; i <= n; i++){
if(!flag[i]){
prim[cnt++] = i;
for(int j = i+i; j <=n; j += i) { //将质数的倍数筛掉
flag[j] = 1;
}
}
}
线性筛法 ( 复杂度O(n) ):
int prim[maxn],cnt = 0; //存放素数并计数
bool flag[maxn]; // 0为质数 1非质数
for(int i = 2; i <= n; i++){
if(!flag[i]){
prim[++cnt] = i;
}
for(int j = 1; j <= cnt; j++) {
if(i * prim[j] > n)
break;
flag[i * prim[j]] == 1;
if(i % prim[j] == 0) //所得的积的最小质因子不由因子提供
break;
}
}
欧拉函数
定义:在数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目。eg. φ(8)=,4,因为1,3,5,7均和8互质。 φ(1)=1, φ(2)=1, φ(3)=2, φ(4)=2, φ(5)=4, φ(6)=2, φ(7)=6, φ(8)=4...
通项公式:φ(x)=
a与b互质即,
int gcd(int a,int b) {
return !b ? a : gcd(b,a%b);
}
性质:
1. 对于素数p,φ(p)=p-1
2.积性函数即对于两个互质数p,q,φ(pq)=φ(p)*φ(q)=(p-1)(q-1)。
3.若n是质数p的k次幂,φ(n)=-=(1-1/p),因为除了p的倍数外,其他数都跟n互质
故 : 相同素因子相乘 φ()=φ()*p 即 φ(n)=-=(1-1/p) 不同素因子相乘 φ(pq)=φ(p)*φ(q)
计算欧拉函数:
朴素算法
int oula(int n) {
int rea = n;
for(int i=2; i<=n; i++) {
if(n%i == 0) {
rea = rea-rea/i;
do{
n /= i;
}while(n%i == 0);
}
}
return rea;
}
优化算法:
int oula(int n) {
int rea = n;
for(int i=2; i*i<=n; i++){
if(n%i == 0) {
rea = rea - rea/i;
do{
n /= i;
}while(n%i==0);
}
}
if(n>1)
rea = rea - rea/n;
return rea;
}
欧拉函数打表:
朴素欧拉打表(复杂度 O(nlog(n))): //递推打表
void getphi() {
int i,j;
for(i=1; i<maxn; i++)
p[i] = i;
for(i=2; i<maxn; i++){
if(p[i]==i){
for(j=i; j<maxn; j+=i)
p[j] = (p[j]/i) * (i-1);
}
}
}
欧拉线性筛打表(复杂度O(n)):
void getphi() {
phi[1] = 1; //存放欧拉数
for(int i=2; i<=n; i++) {
if(!flag[i]){ //flag判断是否为素数,如果是素数
prim[++cnt] = i; //prim存放素数 cnt计数
phi[i] = i-1; //素数的欧拉数是它本身 -1
}
for(int j=1; j<=cnt; j++) {
if(i*prim[j] > n)
break;
flag[i*prim[j]] = 1; //线性筛去素数
if(i%prim[j]==0) { //如果是性质3的情况,相同素因子相乘
phi[i*prim[j]] = phi[i]*prim[j];
break;
}
phi[i*prim[j]] = phi[i]*phi[prim[j]]; //不同素因子相乘
}
}
过了两天回头再看才彻底通透,接下来就是补题了,zkw同学会迟到但一定会到的 /呲牙