题目 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
代码如下 :
View Code
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 }