正题
题目链接:http://poj.org/problem?id=1845
题目大意
求ABAB次方的约数和。答案mod 9901mod9901
解题思路
AA的约数和就是
然后ABAB的约数和就是
(1+p1+p21+p31...+pB∗c11)+(1+p2+p22+p32...+pB∗c22)+...(1+pn+p2n+p3n...+pB∗cnn)(1+p1+p12+p13...+p1B∗c1)+(1+p2+p22+p23...+p2B∗c2)+...(1+pn+pn2+pn3...+pnB∗cn)
然后用等比公式计算每个
(1+px+p2x+p3x...+pB∗cxx)(1+px+px2+px3...+pxB∗cx)
答案
∑i=1n(pB∗cx+1x−1)/(px−1)∑i=1n(pxB∗cx+1−1)/(px−1)
对于每个
(pB∗cx+1x−1)/(px−1)(pxB∗cx+1−1)/(px−1)
((pB∗cx+1x−1) mod 9901)/((px−1) mod 9901)((pxB∗cx+1−1)mod9901)/((px−1)mod9901)
然后计算 ((px−1) mod 9901)((px−1)mod9901)的逆元,然后直接乘。
但是如果 ((px−1) mod 9901)=0((px−1)mod9901)=0,此时乘法逆元不存在,但是 px mod 9901=1pxmod9901=1,所以计算中的 pxpx可以换成1来计算,那么答案就是
B∗c1+1(mod 9901)B∗c1+1(mod9901)
code
#include<cstdio>
#include<algorithm>
#define YMW 9901
using namespace std;
long long a,b,m,ans=1,prime[20],c[20];
void primes(long long n)//质因数分解
{m=0;for(long long i=2;i*i<=n;i++){if(n%i==0){prime[++m]=i,c[m]=0;while(n%i==0) n/=i,c[m]++;}}if(n>1)prime[++m]=n,c[m]=1;
}
long long power(long long x,long long b)//快速幂
{long long sum=1;while(b){if(b&1) sum=sum*x%YMW;x=x*x%YMW;b>>=1;}return sum;
}
int main()
{scanf("%lld%lld",&a,&b);primes(a);//质因数分解for(long long i=1;i<=m;i++){if((prime[i]-1)%YMW==0){ans=(b*c[i]+1)%YMW*ans%YMW;continue;}//没有乘法逆元long long x=power(prime[i],b*c[i]+1);//计算逆元x=(x-1+YMW)%YMW;long long y=prime[i]-1;y=power(y,YMW-2);//计算分子ans=ans*x%YMW*y%YMW;//计算答案}printf("%lld",ans);
}