知识点 - 因数之和 因数个数公式

知识点 - 因数之和 因数个数公式

解决问题类型:

问有几个因数,因数之和,

或者问某些特定约数之和,比如不能被大于4的平方数整除的约数之和(即质因数的次数都为1)

结论

若对 n n n 质因数分解得到 p 1 e 1 ⋅ p 2 e 2 ⋯ p k e k p_1^{e_1} \cdot p_2^{e_2} \cdots p_k^{e_k} p1e1p2e2pkek则有

因数个数公式:

d ( n ) = ( e 1 + 1 ) ⋅ ( e 2 + 1 ) ⋯ ( e k + 1 ) d(n) = (e_1 + 1) \cdot (e_2 + 1) \cdots (e_k + 1) d(n)=(e1+1)(e2+1)(ek+1)

e.g.:设 n = p 1 e 1 ⋅ p 2 e 2 n = p_1^{e_1} \cdot p_2^{e_2} n=p1e1p2e2
1 p 2 p 2 2 … p 2 e 2 1 1 p 2 p 2 2 … p 2 e 2 p 1 p 1 p 1 ⋅ p 2 p 1 ⋅ p 2 2 … p 1 ⋅ p 2 e 2 p 1 2 p 1 2 p 1 2 ⋅ p 2 p 1 2 ⋅ p 2 2 … p 1 2 ⋅ p 2 e 2 ⋮ ⋮ ⋮ ⋮ ⋱ ⋮ p 1 e 1 p 1 e 1 p 1 e 1 ⋅ p 2 p 1 e 1 ⋅ p 2 2 … p 1 e 1 ⋅ p 2 e 2 \begin{array}{c|ccccc} & 1 & p_2 & p_2^2 & \dots & p_2^{e_2} \\\\ \hline 1 & 1 & p_2 & p_2^2 & \dots & p_2^{e_2} \\\\ p_1 & p_1 & p_1 \cdot p_2 & p_1 \cdot p_2^2 & \dots & p_1 \cdot p_2^{e_2} \\\\ p_1^2 & p_1^2 & p_1^2 \cdot p_2 & p_1^2 \cdot p_2^2 & \dots & p_1^2 \cdot p_2^{e_2} \\\\ \vdots & \vdots & \vdots & \vdots & \ddots & \vdots \\\\ p_1^{e_1} & p_1^{e_1} & p_1^{e_1} \cdot p_2 & p_1^{e_1} \cdot p_2^2 & \dots & p_1^{e_1} \cdot p_2^{e_2} \\\\ \end{array} 1p1p12p1e111p1p12p1e1p2p2p1p2p12p2p1e1p2p22p22p1p22p12p22p1e1p22p2e2p2e2p1p2e2p12p2e2p1e1p2e2
显然 d ( n ) = ( e 1 + 1 ) ⋅ ( e 2 + 1 ) d(n)=(e_1 + 1) \cdot (e_2 + 1) d(n)=(e1+1)(e2+1)

因数和公式

σ ( n ) = p 1 e 1 + 1 − 1 p 1 − 1 ⋅ p 2 e 2 + 1 − 1 p 2 − 1 ⋯ p k e k + 1 − 1 p k − 1 \sigma(n) = \frac{p_1^{e_1 + 1} - 1}{p_1 - 1} \cdot \frac{p_2^{e_2 + 1} - 1}{p_2 - 1} \cdots \frac{p_k^{e_k + 1} - 1}{p_k - 1} σ(n)=p11p1e1+11p21p2e2+11pk1pkek+11

e.g.设 n = p 1 e 1 ⋅ p 2 e 2 n = p_1^{e_1} \cdot p_2^{e_2} n=p1e1p2e2
σ ( n ) = ( 1 + p 1 + p 1 2 + ⋯ + p 1 e 1 ) ⋅ ( 1 + p 2 + p 2 2 + ⋯ + p 2 e 2 ) ∵ 1 + p 1 + p 1 2 + ⋯ + p 1 e 1 = p 1 e 1 + 1 − 1 p 1 − 1 ∴ σ ( n ) = p 1 e 1 + 1 − 1 p 1 − 1 ⋅ p 2 e 2 + 1 − 1 p 2 − 1 \sigma(n)=\left(1 + p_1 + p_1^2 + \dots + p_1^{e_1}\right) \cdot \left(1 + p_2 + p_2^2 + \dots + p_2^{e_2}\right)\\ \because 1 + p_1 + p_1^2 + \dots + p_1^{e_1} = \frac{p_1^{e_1 + 1} - 1}{p_1 - 1}\\ \therefore\sigma(n) = \frac{p_1^{e_1 + 1} - 1}{p_1 - 1} \cdot \frac{p_2^{e_2 + 1} - 1}{p_2 - 1} σ(n)=(1+p1+p12++p1e1)(1+p2+p22++p2e2)1+p1+p12++p1e1=p11p1e1+11σ(n)=p11p1e1+11p21p2e2+11

d ( n ) d(n) d(n) and σ ( n ) \sigma(n) σ(n)都是积性函数

​ 可以迪利克雷卷积

质因数的次数都为1的因数和公式

1 + p 1 + p 2 + ⋯ + p k + p 1 ⋅ p 2 + p 1 ⋅ p 3 + ⋯ + p k − 1 ⋅ p k + p 1 ⋅ p 2 ⋅ p 3 + ⋯ + p 1 ⋅ p 2 ⋯ p k − 1 ⋅ p k = ( p 1 + 1 ) ⋅ ( p 1 + 1 ) ⋯ ( p k + 1 ) 1+p_1+p_2+\cdots+p_k+\\p_1\cdot p_2+p_1\cdot p_3+\cdots+ p_{k-1}\cdot p_k+\\p_1\cdot p_2\cdot p_3 +\cdots + p_1\cdot p_2\cdots p_{k-1}\cdot p_k\\ =(p_1+1)\cdot(p_1+1)\cdots(p_k+1) 1+p1+p2++pk+p1p2+p1p3++pk1pk+p1p2p3++p1p2pk1pk=(p1+1)(p1+1)(pk+1)

复杂度:

公式题,复杂度在乘法和快速幂上,

O ( k ∗ l o g e ) O(k*log e) O(kloge)

也可以对 ( 1 + p 1 + p 1 2 + ⋯ + p 1 e 1 ) \left(1 + p_1 + p_1^2 + \dots + p_1^{e_1}\right) (1+p1+p12++p1e1)如果二分递归求:举例来说, 1 + a + a 2 + a 3 + a 4 = ( 1 + a ) ∗ ( 1 + a 2 ) + a 2 ; ( 1 + a ) = 1 ∗ ( 1 + a ) 1+a+a^2+a^3+a^4=(1+a)*(1+a^2)+a^2;(1+a)=1*(1+a) 1+a+a2+a3+a4=(1+a)(1+a2)+a2;(1+a)=1(1+a)。根据奇偶二分下去。直到只有一个数为止。

O ( k ∗ l o g 2 e ) O(k*log^2 e) O(klog2e)

例题

Sumdiv

Let S be the sum of all natural divisors of A^B. Determine S modulo 9901.

代码

#include<cstdio>
#include<cstring>
#ifdef unix
#define LL "%lld"
#else
#define LL "%I64d"
#endif
#define mod 9901 
using namespace std;
typedef long long ll;
const int N=1e5+10;
ll tot,c[N/3],prime[N/3];
bool check[N]={1,1};
void get_prime(){
    ll n=10010;
    for(ll i=2;i<=n;i++){
        if(!check[i]) prime[++tot]=i;
        for(ll j=1;j<=tot&&i*prime[j]<=n;j++){
            check[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}
ll mul(ll a,ll p,ll M){
    ll res=0;
    for(;p;p>>=1,a=(a+a)%M) if(p&1) res=(res+a)%M;
    return res;
}
ll fpow(ll a,ll p,ll M){
    ll res=1;
    for(;p;p>>=1,a=mul(a,a,M)) if(p&1) res=mul(res,a,M);
    return res;
}
void factor(ll A,ll B){
    ll ans=1;
    for(ll i=1;prime[i]*prime[i]<=A;i++){
        if(A%prime[i]==0){
            ll num=0;
            while(A%prime[i]==0) num++,A/=prime[i];
            ll MOD=(prime[i]-1)*mod;
            ans*=(fpow(prime[i],num*B+1,MOD)+MOD-1)/(prime[i]-1);
            ans%=mod;
        }
    }
    if(A>1){
        ll MOD=mod*(A-1);
        ans*=(fpow(A,B+1,MOD)+MOD-1)/(A-1);
        ans%=mod;
    }
    printf(LL"\n",ans);
}
int main(){
    get_prime();
    for(ll A,B;scanf(LL LL,&A,&B)==2;) factor(A,B);
    return 0;
}
//递归二分代码:
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
const int mod=9901;
int pow_mod(int a,int b)
{
	a=a%mod;
	int s=1;
	while(b)
	{
		if(b&1)
			s=(s*a)%mod;
		a=(a*a)%mod;
		b=b>>1;
	}
	return s;
}
int sum(int a,int b)//求1+a+a^2+...+a^b
{
	if(b==1)return 1;
	if(b&1)return (sum(a,b/2)*(1+pow_mod(a,b/2+1))+pow_mod(a,b/2))%mod;
	else return sum(a,b/2)*(1+pow_mod(a,b/2))%mod;
}
int main()
{
	int a,b;
	while(cin>>a>>b)
	{
	 	if(a<=1||b==0){cout<<1<<endl;continue;}
		int ans=1,i,j,k,t,n,m;
		n=(int)sqrt(a+0.5);
		for(i=2;i<=n;i++)
		{
			if(a%i==0)
			{
				t=0;
				while(a%i==0){
					a=a/i;
					t++;
				}
				ans=ans*sum(i,t*b+1)%mod;
			}
		}
		if(a>1)
			ans=ans*sum(a,b+1)%mod;
		cout<<(ans+mod)%mod<<endl;	
	}
	return 0;
}
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Best KeyBoard

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值