输入a,b,求a^b的所有因子之和

 题目 poj的1845
 

分解a的质因数a=p1^t1*p2^t1........

每个质因数对sum的贡献: 当除去质因数p1时的因数和为sum,当计入p1时,因子和变成sum*p1^0+sum*p1^1+sum*p1^2......+sum*p1^t1

也就是所有的sum=【1+p1+p1^2+p1^3+...+p1^t1】*【p2.....】【p3...】

然后由于是a^b,所以最后是

sum=sum=【1+p1+p1^2+p1^3+...+p1^(t1*b)】*【p2.....】【p3...】

显然就是求关于a的所有质因数的一个 等比数列之和前n项和.

用逆元,用公比求和公式  1+pi+...+pi^n=(pi^(n+1)-1)/(pi-1)
  由于涉及到除法,且mod=9901为素数,所以可以用费马小定理求逆元,只是要注意mod比较小,
当【prim[i]-1】%mod==0(分母是mod的倍数)时,逆元不存在,不过此时恰好公比为1啦,前n项和答案就是n
代码如下 :
 1 int pime[103];
 2 int s[103];
 3 int cnt=0;
 4 void init(ll n)//这个函数很巧妙 可以不打表找素数
 5 {
 6     for(ll i=2;i*i<=n;i++)
 7     {
 8         if(n%i==0)//如果n能被i正除,i就是素数,自己好好想一想,为什么
 9         {
10             pime[++cnt]=i;//是素数用数组记录下来
11             while(n%i==0)//然后找该素数有几个
12             {
13                 n/=i;
14                 s[cnt]++;//符合条件的第cnt个素数累加
15             }
16         }
17     }//循环继续查找
18     if(n>1)pime[++cnt]=n,s[cnt]++;//n==1说明已经除尽了,反之没有因为刚开始的是算sqrt(n)以内的素数。
19 }
20 ll ks(ll a,ll b)//快速幂
21 { ll z=1;
22     while(b)
23     {
24         if(b&1)z=(z*a)%mod;
25         a=(a*a)%mod;
26         b>>=1;
27     }
28     return z;
29 }
30 int main()
31 {
32  ll a,b;
33    cin>>a>>b;
34    //if(a<=1||b==0)
35   // {
36   //     cout<<1;return 0;
37   // }//可要可不要
38    init(a);
39    ll sum=1;
40    for(int i=1;i<=cnt;i++)
41    {
42        if((pime[i]-1)%mod==0) sum=sum*(s[i]*b+1)%mod;
43        else sum=(sum*(ks(pime[i],s[i]*b+1)-1)*ks(pime[i]-1,mod-2))%mod;//用等比数列求和公式
44    }cout<<(sum+mod)%mod;
45 }
View Code

 

转载于:https://www.cnblogs.com/zxz666/p/10455894.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值