唯一分解定理
一个数n肯定能被分解成 n=p1^a1 * p2^a2 . . .*pn^an
因为一个数肯定是由合数和质数构成的,合数又可以分解成质数和合数,最后递归下去就会变成质数的乘积
如 36 -〉 4*9 或者 6*6 -〉 2*3*2*3 -〉2^2*3^2
最后化成了质数相乘的形式
好,现在给出唯一分解定理的两个小应用
1,求出数n的因子个数
(1+a1)*(1+a2)*(1+a3)*(1+a4)......*(1+an)
a1,a2,这些分别是素数因子的幂次数
因为当我的a1=3时那我n的因子肯定会有 p1^0 p1^1 p1^2 p1^3 这四个数
然后再和p2的个数搭配起来就是两个数的因子数相乘了 p1^x 可以与 p2^y 随意搭配,所以进行乘法
2.求所有的因子之和
这个其实也就是和上面这个一样的道理,不过我们求的是和,所以我们要把所有的因子和求出来
公式:(q1^0+q1^1+q1^2.....q1^a1)*(q2^0+q2^1+q2^2.....q2^a2)*........*(qn^0+qn^n+qn^2.....qn^an)
因为每一项都有个1就代表是原来的自己那一项,后面都是组合项
模板:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <list>
#include <bitset>
#include <climits>
#define lowbit(x) (x & -x)
#define gcd(a, b) __gcd(a, b)
#define mset(a, x) memset(a, x, sizeof(a))
#define FIN freopen("input", "r", stdin)
#define FOUT freopen("output", "w", stdout)
const int INF = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-6;
const int MAX = 1e5 + 10;
const int mod = 1e9 + 7;
typedef long long ll;
using namespace std;
inline ll lcm(ll a, ll b) {
return a / gcd(a, b) * b;
}
inline ll qpow(ll a, ll b) {
ll r = 1, t = a;
while(b) {
if(b & 1)
r = (r * t) % mod;
b >>= 1;
t = (t * t) % mod;
}
return r;
}
inline ll inv1(ll b) {
return qpow(b, mod - 2);
}
inline ll inv2(ll b) {
return b == 1 ? 1 : (mod - mod / b) * inv2(mod % b) % mod;
}
inline ll exgcd(ll a, ll b, ll &x, ll &y) {
if(!b) {
x = 1;
y = 0;
return a;
}
ll r = exgcd(b, a % b, y, x);
y -= (a / b) * x;
return r;
}
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0 };
ll n;
int k = 0;
struct Factor { //存分解后的素因子和该素因子个数
ll factor, Count;
Factor() {
Count = 0;
}
} fa[100005];
void decompose(ll x) { //唯一分解定理
ll ans = 0;
for(ll i = 2; i * i <= x; i++) {
if(x % i == 0) {
fa[k].factor = i;
while(x % i == 0) {
x /= i;
fa[k].Count++;
}
k++;
}
}
if(x > 1) {
fa[k].factor = x;
fa[k].Count = 1;
k++;
}
}
ll dcpCount(ll x) { //所有因子的个数(包括1)
ll ans = 1;
for(ll i = 2; i * i <= x; i++) {
if(x % i == 0) {
ll temp = 0;
while(x % i == 0) {
x /= i;
temp++;
}
ans *= (temp + 1);
}
}
if(x > 1)
ans *= 2;
return ans;
}
ll dcpSum(ll x) { //所有因子的和(包括1)
//(q1^0+q1^1+q1^2.....q1^a1)*(q2^0+q2^1+q2^2.....q2^a2)*........*(qn^0+qn^n+qn^2.....qn^an)
ll ans = 1;
for(ll i = 2; i * i <= x; i++) {
if(x % i == 0) {
ll temp = 1;
while(x % i == 0) {
x /= i;
temp *= i;
}
ans *= (temp * i - 1) / (i - 1);//根据x+x^2+x^3+...+x^n=[x^(n+1)-x]/(x-1)
}
}
if(x > 1)
ans *= (1 + x);
return ans;
}
int main () {
while(scanf("%lld", &n) != EOF) {
ll temp = 1;
memset(fa, 0, sizeof(fa));
k = 0;
decompose(n);
for(int i = 0; i < k; i++) {
if(i)
printf(" * ");
printf("%lld^%lld", fa[i].factor, fa[i].Count);
temp *= qpow(fa[i].factor, fa[i].Count);
}
printf(" = %lld\n", temp);
printf("因子和: %lld\n", dcpSum(n));
printf("因子个数: %lld\n", dcpCount(n));
}
return 0;
}