约数之和
Posted hhyx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了约数之和相关的知识,希望对你有一定的参考价值。
poj链接
# 题意
求A^B 的所有约数的和
答案 mod 9901
# 题解
唯一分解定律:一个数由质数和合数构成,合数可分解成质数和合数,最后递归下去会变成质数乘积
每一个大于1的数都可以分解成有限个质数的积,不管质因数的顺序,分解是唯一的,
将A分解质因数后表示为 P1c1 * P2c2 *.......* Pncn
AB 的质因数和就是
(1 + P1 + P12 + .... P1B*c1) * (1 + P2 + P22 + .... P2B*c2) * ....(1 + Pn + Pn2 + .... PnB*cn)
上面每个项都是等比数列,使用等比数列求和需要做除法,还要 mod 9901,模运算只对加、减、乘有分配律
所以不能直接对分子分母取模再运算,用分治法对等比数列求和:
定义sum(p,c)即公比为 p,首项为1,长度为c的和
c为奇数时候:
sum( p , c )=(1 + p + ...... + p(c-1)/2) + (p(c+1)/2 + ...... + pc)
=(1 + p + ...... + p(c-1)/2) + p(c+1)/2 * (1 + p + ...... + p(c-1)/2)
=(1 + p(c+1)/2) * sum( p , (c-1)/2 )
c为偶数:
sum( p , c )=(1 + p + ...... + pc/2-1) + (pc/2 + ...... + pc)
=(1 + p + ...... + pc/2-1) + pc/2 * (1 + p + ...... + pc/2)
=(1 + p + ...... + pc/2-1) + pc/2 * (1 + p + ...... + pc/2-1) + pc
=(1 + pc/2) * sum( p , c/2-1 ) + pc
1 #include <iostream>
2 using namespace std;
3 const int mod=9901;
4 typedef long long ll;
5 inline ll qmi(ll a,ll b){
6 ll ans=1%mod;
7 while(b){
8 if(b&1)
9 ans=ans*a%mod;
10 a=a*a%mod;
11 b>>=1;
12 }
13 return ans;
14 }
15 ll sum(int p,int c){//求sum(p,c)首项为1,公比为p,长度为c的等比数列的和
16 if(c==0) return 1;
17
18 if(c&1)//奇数
19 return (( 1+qmi(p,(c+1)>>1) )*sum(p,(c-1)>>1))%mod;
20 else //偶数
21 return ((1+qmi(p,c>>1) )*sum(p,c/2-1)+qmi(p,c))%mod;
22 }
23 int main(){
24 ios::sync_with_stdio(0);
25 cin.tie(0);
26 cout.tie(0);
27 int n,m;
28 cin>>n>>m;
29 if (n==0)
30 {
31 cout<<0<<endl;
32 return 0;
33 }
34 int ans=1;//如果A为素数,则约数只有自己
35 for(int i=2;i<=n;i++){
36 int s=0;//记录次数
37 while(n%i==0){//可以被整除
38 s++;
39 n/=i;
40 }
41 if(s)
42 ans=ans*sum(i,s*m)%mod;
43 }
44
45 cout<<ans<<endl;
46 return 0;
47 }
以上是关于约数之和的主要内容,如果未能解决你的问题,请参考以下文章