Sumdiv POJ - 1845(分解质因数+小学奥数题+快速幂+等比数列求和递归公式推导)

题意:传送门
题解:要算 A B A^B AB的所有约数之和 % 9901 \%9901 %9901,首先可以对 A A A进行质因数分解 A = p 1 k 1 ∗ p 2 k 2 ∗ ⋯ ∗ p n k n A=p_1^{k_1}*p_2^{k_2}*\cdots*p_n^{k_n} A=p1k1p2k2pnkn约数之和的取法有多少种呢? n u m = ( k 1 + 1 ) ∗ ( k 2 + 1 ) ∗ ⋯ ∗ ( k n + 1 ) num=(k_1+1)*(k_2+1)*\cdots*(k_n+1) num=(k1+1)(k2+1)(kn+1)也就是 A A A的所有约数之和可以表示为 s u m = ( 1 + p 1 1 + p 1 2 + ⋯ + p 1 k 1 ) ∗ ( 1 + p 2 1 + p 2 2 + ⋯ + p 2 k 2 ) ∗ ⋯ ∗ ( 1 + p n 1 + p n 2 + ⋯ + p n k n ) sum=(1+p_1^1+p_1^2+\cdots+p_1^{k_1})*(1+p_2^1+p_2^2+\cdots+p_2^{k_2})*\cdots*(1+p_n^1+p_n^2+\cdots+p_n^{k_n}) sum=(1+p11+p12++p1k1)(1+p21+p22++p2k2)(1+pn1+pn2++pnkn)这其实也就是个小学奥数题,然后有个幂 B B B,那么质因数分解完相对应的每个都乘上 B B B,变成: A B = p 1 k 1 ∗ B ∗ p 2 k 2 ∗ B ∗ ⋯ ∗ p n k n ∗ B A^B=p_1^{k_1*B}*p_2^{k_2*B}*\cdots*p_n^{k_n*B} AB=p1k1Bp2k2BpnknB然后对应的约数之和取法就有: n u m = ( k 1 ∗ B + 1 ) ∗ ( k 2 ∗ B + 1 ) ∗ ⋯ ∗ ( k n ∗ B + 1 ) num=(k_1*B+1)*(k_2*B+1)*\cdots*(k_n*B+1) num=(k1B+1)(k2B+1)(knB+1)对应的 A B A^B AB的所有约数之和就是: s u m = ( 1 + p 1 1 + p 1 2 + ⋯ + p 1 k 1 ∗ B ) ∗ ( 1 + p 2 1 + p 2 2 + ⋯ + p 2 k 2 ∗ B ) ∗ ⋯ ∗ ( 1 + p n 1 + p n 2 + ⋯ + p n k n ∗ B ) sum=(1+p_1^1+p_1^2+\cdots+p_1^{k_1*B})*(1+p_2^1+p_2^2+\cdots+p_2^{k_2*B})*\cdots*(1+p_n^1+p_n^2+\cdots+p_n^{k_n*B}) sum=(1+p11+p12++p1k1B)(1+p21+p22++p2k2B)(1+pn1+pn2++pnknB)知道了这个以后还得了解一个等比数列求和的公式推导: s u m ( p , c ) = 1 + p + p 2 + ⋯ + p c sum(p,c)=1+p+p^2+\cdots+p^c sum(p,c)=1+p+p2++pc如果c为奇数 s u m ( p , c ) = ( 1 + p + ⋯ + p c − 1 2 ) + ( p c + 1 2 + ⋯ + p c ) sum(p,c)=(1+p+\cdots+p^{\frac{c-1}{2}})+(p^{\frac{c+1}{2}}+\cdots+p^c) sum(p,c)=(1+p++p2c1)+(p2c+1++pc) s u m ( p , c ) = ( 1 + p + ⋯ + p c − 1 2 ) + p c + 1 2 ∗ ( 1 + p + ⋯ + p c − 1 2 ) sum(p,c)=(1+p+\cdots+p^{\frac{c-1}{2}})+p^{\frac{c+1}{2}}*(1+p+\cdots+p^{\frac{c-1}{2}}) sum(p,c)=(1+p++p2c1)+p2c+1(1+p++p2c1) s u m ( p , c ) = ( 1 + p c + 1 2 ) ∗ s u m ( p , c − 1 2 ) sum(p,c)=(1+p^{\frac{c+1}{2}})*sum(p,\frac{c-1}{2}) sum(p,c)=(1+p2c+1)sum(p,2c1)如果c为偶数的话,那么也可以推导公式,可以差分为 s u m ( p , c ) = p ∗ s u m ( p , c − 1 ) + 1 sum(p,c)=p*sum(p,c-1)+1 sum(p,c)=psum(p,c1)+1或者推导为公式: s u m ( p , c ) = ( 1 + p c 2 ) ∗ s u m ( p , c 2 − 1 ) + p c sum(p,c)=(1+p^{\frac{c}{2}})*sum(p,\frac{c}{2}-1)+p^c sum(p,c)=(1+p2c)sum(p,2c1)+pc这个可自行推导。
附上代码:

#include<iostream>
using namespace std;
const int mod=9901;
int a,b;
int qpow(int a,int b)
{
    a%=mod;
    int res=1;
    for(int i=b;i;i>>=1,a=a*a%mod)if(i&1)res=res*a%mod;
    return res;
}
int sum(int p,int k)
{
    if(k==0)return 1;
    else if(k%2==0)return ((1+qpow(p,k/2))%mod*sum(p,k/2-1)%mod+qpow(p,k))%mod;
    else return ((1+qpow(p,(k+1)/2))%mod*sum(p,(k-1)/2)%mod)%mod;
}
int main()
{
    cin>>a>>b;
    int res=1;
    for(int i=2;i<=a;i++){
        int s=0;
        while(a%i==0){
            s++;
            a/=i;
        }
        if(s)res=res*sum(i,s*b)%mod;
    }
    if(!a)res=0;
    cout<<res<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值