Sumdiv
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 30077 | Accepted: 7410 |
Description
Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S modulo 9901 (the rest of the division of S by 9901).
Input
The only line contains the two natural numbers A and B, (0 <= A,B <= 50000000)separated by blanks.
Output
The only line of the output will contain S modulo 9901.
Sample Input
2 3
Sample Output
15
Hint
2^3 = 8.
The natural divisors of 8 are: 1,2,4,8. Their sum is 15.
15 modulo 9901 is 15 (that should be output).
题意:求A的B次方的所有因子的和mod9901。
思路:对数论不太熟练的同学非常适合做这道题。(比如我)
显然按唯一分解定理对A分解成,其中p1,p2,...,px都是质数。
B次方,即把k1,k2,...,kx都乘上B即可。
根据约数求和公式(其实自己想想就能出来),答案为
根据等比数列求和公式,第i个括号里的和为
取模有除法怎么办?逆元!
这就完了?错!
逆元要注意 a/b%mod==a*power(b,mod-2)%mod的前提是a不能整除mod!!!
整除了怎么办?
我们把a对 mod*(a-1) 这个数取模,最后就可以除掉(a-1)了,而且a肯定与(a-1)*mod互质(想想是不是)。
注意long long和mod。
代码:
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<queue>
#include<vector>
#include<map>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const double pi=acos(-1.0);
const int maxn=200010;
const ll mo=9901;
ll n,m,k;
ll ans,tmp,cnt;
ll c[maxn],num[maxn];
ll power(ll a,ll n,ll mo) //a的n次方mod
{
ll ans=1;
a=a%mo;
while (n)
{
if(n&1) ans=(ans*a)%mo;
n>>=1;
a=(a*a)%mo;
}
return ans;
}
int main()
{
int T,cas=1;
while(scanf("%lld%lld",&n,&m)!=EOF)
{
cnt=0;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
c[cnt]=i;
num[cnt]=0;
while(n%i==0)
{
n/=i;
num[cnt]++;
}
num[cnt]*=m;
cnt++;
}
}
if(n!=1)//n是个质数
{
c[cnt]=n;
num[cnt]=m;
cnt++;
}
ll ans=1;
for(int i=0;i<cnt;i++)
{
ll sum;
if((c[i]-1)%mo==0)
{
sum=power(c[i],num[i]+1,mo*(c[i]-1))-1;
sum+=mo*(c[i]-1);
ans=ans*(sum/(c[i]-1)%mo)%mo;
}
else
{
sum=power(c[i],num[i]+1,mo)-1;
sum+=mo;
ans=(ans*sum%mo*power(c[i]-1,mo-2,mo)%mo)%mo;
}
}
printf("%lld\n",ans%mo);
}
return 0;
}