若整数n除以整数d的余数为0,即d能整除n,则称d是n的约数 ,n是d的倍数,记为 d|n
唯一分解定理(算数基本定理):任一大于1的自然数?,都可以唯一分解为有限个素数之积:
N=p1^c1*p2^c2*p3^c3*....*pr^cr
N的正约数个数:num=(c1+1)*(c2+1)*(c3+1)*...(cm+1)
N的正约数的和:sum=(1+p1+p1^2+...+p1^c1)*(1+p2+p2^2+...p2^c2)*...(1+pm+pm^2+pm^3+...+pm^m)
唯一分解定理:
//pri是素因子,sumx是该素因子上的指数b
void getpri(ll m)//分解质因数
{
for(ll i=2;i*i<=m;i++)
{
while(m%i==0)
{
pri[index]=i;
sumx[index]++;
m/=i;
}
if(sumx[index]) index++;
}
if(m>1) pri[index]=m, sumx[index++]=1;
}
求多个数的素因子(数不是很大)
素因子保存在中
#include<bits/stdc++.h>
#define MAXN 1000005
#define ll long long
using namespace std;
/*
对大量1~100万的数进行素数筛
*/
int tot;
int isprime[MAXN];
int prime[MAXN];
int a[MAXN];
vector<int> pos[MAXN];//保存素数
void get_prime() //欧拉筛
{
tot=0;
memset(isprime,1,sizeof(isprime));
isprime[0]=isprime[1]=0;
for(int i=2;i<=MAXN;i++)
{
if(isprime[i]) prime[tot++]=i;
for(int j=0;j<tot;j++)
{
if(i*prime[j]>MAXN) break;
isprime[i*prime[j]]=0;
if(i%prime[j]==0) break;
}
}
}
void dec(int p)
{
int n=a[p];
for(int i=0;i<tot && prime[i]*prime[i]<=n;i++)
{
if(n%prime[i]==0)
{
pos[p].push_back(prime[i]);
while(n%prime[i]==0)
n/=prime[i];
}
}
if(n>1) pos[p].push_back(n);
}
int main()
{
int n;
get_prime();
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
dec(i);
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<pos[i].size();j++)
printf("%d ",pos[i][j]);
printf("\n");
}
return 0;
}
大量因子分解(包括非素因子):
下面一个会爆1ms
#include<bits/stdc++.h>
#define ll long long
#define MAXN 1000005
using namespace std;
int pp[MAXN]={0};//求和
vector<int> p[MAXN];
void init()//预先处理因子
{
for(int i=1;i<=MAXN;i++)
{
for(int j=i;j<=MAXN;j+=i)
{
p[j].push_back(i);
//pp[j]+=i;
}
}
}
分解单个数的因子
#include <bits/stdc++.h>
using namespace std;
const int Maxn = 1e5+10;
const int Mod = 1e9+7;
int b[Maxn], dp[Maxn];
vector <int> a[Maxn];
stack <int> sk;
void solve (int x)// 约数打表
{
int tmp = x;
for (int i = 1; i*i <= tmp; ++i)
{
if (tmp % i != 0) continue;
if (i*i == tmp)
a[x].push_back (i);
else
a[x].push_back (i); sk.push(tmp/i);
}
while (!sk.empty())
{
a[x].push_back (sk.top());
sk.pop();
}
}
int main()
{
solve(100);
for(int i=0;i<a[100].size();i++)
cout<<a[100][i]<<endl;
}
求单个数因子个数:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
#define MAXN 2000005
int prime[MAXN],tot,vis[MAXN];
void getprime()
{
tot=0;
memset(vis,0,sizeof(vis));
for(int i=2;i<MAXN;i++)
{
if(vis[i]==0)
prime[tot++]=i;
for(int j=0;j<tot&&prime[j]*i<MAXN;j++)
{
vis[prime[j]*i]=1;
if(i%prime[j]==0)
break;
}
}
}
ll solve(ll n)//求因子个数
{
ll sum = 1;
for(int i=0;i<tot&&prime[i]*prime[i]<=n;i++)
{
if(n%prime[i]==0)
{
int ans=0;
while(n%prime[i]==0)
{
ans++;
n /= prime[i];
}
sum*=(1+ans);
}
}
if(n>1)
sum*=2;
return sum;
}
int main()
{
ll x;
getprime();
scanf("%lld",&x);
printf("%lld\n",solve(x));
return 0;
}
求最小素因子和最大素因子
转载自:https://blog.youkuaiyun.com/wsniyufang/article/details/6623576
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define MAXN 10
#define C 16381
using namespace std;
typedef __int64 I64;
I64 min;
I64 multi(I64 a, I64 b, I64 n){
I64 tmp = a % n, s = 0;
while(b){
if(b & 1) s = (s + tmp) % n;
tmp = (tmp + tmp) % n;
b >>= 1;
}
return s;
}
I64 Pow(I64 a, I64 b, I64 n){
I64 tmp = a % n, s = 1;
while(b){
if(b & 1) s = multi(s, tmp, n);
tmp = multi(tmp, tmp, n);
b >>= 1;
}
return s;
}
int witness(I64 a, I64 n){
I64 u = n - 1, t = 0, i, x, y;
while(!(u & 1)) u >>= 1, t ++;
x = Pow(a, u, n);
for(i = 1; i <= t; i ++){
y = multi(x, x, n);
if(y == 1 && x != 1 && x != n -1) return 1;
x = y;
}
if(x != 1) return 1;
return 0;
}
int test(I64 n){
I64 a;
int i;
if(n == 2) return 1;
if(n < 2 || !(n & 1)) return 0;
srand((I64)time(0));
for(i = 0; i < MAXN; i ++){
a = ((I64) rand()) % (n - 2) + 2;
if(witness(a, n)) return 0;
}
return 1;
}
I64 gcd(I64 a, I64 b){
return b ? gcd(b, a % b) : a;
}
I64 pollard_rho(I64 n, I64 c){
I64 x, y, d, i = 1, k = 2;
srand((I64)time(0));
x = ((I64) rand()) % (n - 1) + 1;
y = x;
while(1){
i ++;
x = (multi(x, x, n) + c) % n;
d = gcd(y - x + n, n);
if(d != 1 && d != n) return d;
if(y == x) return n;
if(i == k) y = x, k <<= 1;
}
}
void find(I64 n, I64 c){
I64 r;
if(n <= 1) return;
if(test(n)){
if(min > n) min = n;
return;
}
r = pollard_rho(n, c--);
find(n / r, c);
find(r, c);
}
I64 MaxPrimeFactor(I64 n)
{
if(test(n))
return n;
I64 k=-1,g;
min=n;
find(n,C);
g=MaxPrimeFactor(min);
k=g>k?g:k;
g=MaxPrimeFactor(n/min);
k=g>k?g:k;
return k;
}
int main(){
I64 n;
while(~scanf("%I64d", &n))
{
min = n; //min表示n的最小素因子
find(n, C); //找出n的最小素因子
printf("%I64d\n",min);
printf("%I64d\n",MaxPrimeFactor(n));//求n的最大素因子
}
return 0;
}