因子

若整数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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值