您的位置:首页 > 其它

求A^B的所有约数和 POJ1845

2015-08-13 09:52 274 查看
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;

long long arr1[100000];
long long MOD=9901;

long long multi(long long a,long long b)
{
if(b==0)
return 1;
if(b==1)
return a;
long long ret=multi(a,b/2);
ret=(ret*ret)%MOD;
if(b&1)
ret=ret*a%MOD;
return ret;
}

long long fsum(long long p,long long n)  //递归二分求 (1 + p + p^2 + p^3 +...+ p^n)%mod
{                          //奇数二分式 (1 + p + p^2 +...+ p^(n/2)) * (1 + p^(n/2+1))
if(n==0)               //偶数二分式 (1 + p + p^2 +...+ p^(n/2-1)) * (1+p^(n/2+1)) + p^(n/2)
return 1;
if(n%2)  //n为奇数,
return (fsum(p,n/2)*(1+multi(p,n/2+1)))%MOD;
else     //n为偶数
return (fsum(p,n/2-1)*(1+multi(p,n/2+1))+multi(p,n/2))%MOD;
}

int main()
{
long long a,b;
while(scanf("%I64d%I64d",&a,&b)!=EOF)
{
memset(arr1,0,sizeof(arr1));
long long sum=a;
long long ans1=1;
double s=sqrt((double)a);
int num=0;
for(int i=2;i<=s;i++)
{
int flag=0;
while(sum%i==0)
{
sum=sum/i;
flag++;
arr1[num]=i;
}
if(flag)
{
flag*=b;
num++;
ans1=(ans1*fsum(arr1[num-1],flag))%MOD;
//     cout<<arr1[num-1]<<" "<<flag<<endl;
//     cout<<ans1<<endl;
}
}
if(sum!=1)
{
arr1[num]=sum;
ans1=(ans1*fsum(sum,b))%MOD;
num++;
}
cout<<ans1<<endl;
}
return 0;
}


View Code
求一个数的所有约数和

ans=(1+q1^1+q1^2+......+q1^k1)*(1+q2^1+q2^2+......+q2^k2)*......(1+qn^1+qn^2+......qn^kn)

此题不能用等比数列前n项和,因为要求逆元需要该数与MOD互质,而此题中MOD过小,该数可能为MOD的整数倍,所以要用二分的方法直接求

(1+p+p^2+p^3)=(1+p)*(1+p^2)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: