首先需要知道正整数的唯一分解式:
N=(p1^a1)*(p2^a2)*.........*(pn^an);
那么N的所有因子之和为(1+p1+p1^2+.....+p1^a1)*(1+p2+p2^2+.......+p2^a2)*......(1+pn+pn^2+.....pn^an);
那么怎么去求p1,.....pn,a1......an的值呢?猛戳 http://blog.csdn.net/u014686462/article/details/37889583 讲的不能再详细了。
另外就是要求所有因子的和了,注意这里不能直接用等比数列公式,因为它不满足模运算,所以就采用了二分递归求和。据说也可以用求逆元来求和,待会研究研究。
代码:
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const int MOD=9901;
int N;
LL p[1000],num[1000];
LL exp_mod(LL a,LL b)
{
LL ans=1;
a%=MOD;
while(b)
{
if(b&1) ans=(ans*a)%MOD;
a=(a*a)%MOD;
b>>=1;
}
return ans;
}
LL sum(LL p,LL n)
{
if(n==0)
return 1;
if(n%2)
return (sum(p,n/2)*(1+exp_mod(p,n/2+1)))%MOD;
else
return (sum(p,n/2-1)*(1+exp_mod(p,n/2+1))+exp_mod(p,n/2))%MOD;
}
void ph(LL x)
{
N=0;
memset(p,0,sizeof(p));
memset(num,0,sizeof(num));
for(LL i=2;i<(LL)sqrt(1.0*x)+1;i++)
{
if(x%i==0)
{
while(x%i==0)
{
num[N]++;
x/=i;
}
p[N++]=i;
}
}
if(x>1) num[N]++,p[N++]=x;
}
int main()
{
LL a,b;
while(cin>>a>>b)
{
if(a==0) puts("0");
else
{
ph(a);
//for(int i=0;i<N;i++)
// printf("%d %d\n",p[i],num[i]);
LL ans=1;
for(int i=0;i<N;i++)
{
ans=(ans*(sum(p[i],b*num[i])%MOD))%MOD;
}
cout<<ans<<endl;
}
}
return 0;
}
用逆元的做法:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<stack>
using namespace std;
typedef long long LL;
const LL M=9901;
LL p[1000],num[1000];
int N;
LL exp_mod(LL a,LL b)
{
LL ans=1;
a%=M;
while(b)
{
if(b&1) ans=(ans*a)%M;
a=(a*a)%M;
b>>=1;
}
return ans;
}
void phi(LL x)
{
N=0;
memset(p,0,sizeof(p));
memset(num,0,sizeof(num));
for(LL i=2;i<(LL)sqrt(1.0*x)+1;i++)
{
if(x%i==0)
{
while(x%i==0)
{
num[N]++;
x/=i;
}
p[N++]=i;
}
}
if(x>1) num[N]++,p[N++]=x;
}
int main()
{
freopen("in.txt","r",stdin);
LL a,b;
while(cin>>a>>b){
if(a==0) puts("0");
else
{
phi(a);
LL ans=1;
for(int i=0;i<N;i++)
{
if(p[i]%M==0) continue;
if(p[i]%M==1)
{
ans=ans*(num[i]*b+1)%M;
continue;
}
LL c=exp_mod(p[i]-1,M-2);
ans=(ans*(c*(exp_mod(p[i],b*num[i]+1)-1+M)%M)%M)%M;
}
cout<<ans<<endl;
}
}
return 0;
}
<span style="color:#FF0000;">if(p[i]%M==0)
if(p[i]%M==1)</span>
这两个特判一定要注意!!!