因数分解:
算术基本定理可以描述为:对于每个整数n,都可以唯一分解成素数的乘积
$n = p_1p_2p_3…p_k$
这里的素数并不要求是不一样的,所以可以将相同的素数进行合并,采用素数幂的乘积进行表示
$n = p_1^{e_1} p_2^{e_2} …p_k^{e_k}$
素数拆分:
(需要素数筛):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| int prime[MAX_1]; int visit[MAX_1]; int flag[MAX_1]; void Prime(int n) { for(int i = 2;i <= n;i++) { if(!visit[i]) { prime[++prime[0]] = i; flag[i] = 1; } for(int j = 1;j <= prime[0] && i*prime[j] <= n;j++) { visit[i*prime[j]] = 1; if(i % prime[j] == 0) break; } } }
|
因子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| map<int,int> cnt; while(k != 1) { for(int i = 1;i < prime[0];i++) { if(flag[k]) { cnt[k]++; k=1; break; } if(k % prime[i] == 0) { cnt[prime[i]]++; k /= prime[i]; break; } } }
|
因子个数:
$cntx = (e_1 + 1)(e_1+1)…(e_k+1)$
1 2 3 4 5 6
| map<int,int>::iterator it; int cntx = 1; for(it = cnt.begin();it != cnt.end();it++) { cntx *= (it->second + 1); }
|
因子和:
1 2 3 4 5 6 7 8 9 10
| map<int,int>::iterator it; for(it = cnt.begin();it != cnt.end();it++) { int k = 1; for(int i = 0;i <= it->second;i++) { k *= it->first; } ans *= (k-1) / (it->first -1); }
|