题目大意:给出A,B 求出A的B次幂的约数(因子)之和
思路: 这道题运用到数论的三大内容
1> 任意一个整数都可以写成质数的N次幂的乘积
A=(p1^ k1)*(p2^k2)*(p3^k3)...........(pn^kn)
其中p1,p2,p3.....pn 为素数
2> 某数A的质因子M之和
M= (p1^0+p1^1+p1^2.......+p1^k1)*(p2^0+p2^1+p2^2.......+p2^k2)*........
3> 同余定理
(A+B) mod X= (AmodX + BmodX) modX;
(A*B) mod X= (AmodX * BmodX) modX;
应用到这道题中:
第一步:分解A
首先对A进行素数的分解,从2开始,进行分解
如: 在A%2!=0 的情况下 记录A/2的次数以得到它的幂,并且
不断进行A/=2
如此,对之后的每个素数进行这样的运算,知道A=1
但是,当A本身就是一个素数时,无法进行分解,此时把A存入。
第二步:计算每一个Sum=(p^0+p^1+p^2.........p^n)
当n是奇数时 : Sum=(p^0+p^1.....p^n/2)(1+p^n/2);
当n是偶数时 : Sum=(p^0+p^1.....p^n/2-1)(1+p^n/2+1)+p^n/2 ;
如此,就可以把求Sum的过程看成一个递归函数,不断递归,更加方便求出
第三步:计算p^n
根据一下定理:
q1=p*p; 则 n=n/2;
q2=q1*q1; 则n=n/2;
........
如此 2^8=256 只需要计算3次
2*2=4 4*4 =16 16*16=256;
sum=1
若n为奇数则可以先进行一次乘法,使得n变为偶数
按照n为偶数的方式不断进行p=p*p sum*=p 直到 n=0
代码如下:
#include <queue>
#include <stack>
#include <math.h>
#include <vector>
#include <limits.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <functional>
using namespace std;
#define size 10000
#define mod 9901
__int64 get(__int64 p,__int64 n)
{
__int64 result=1;
while(n>0)
{
if(n%2)
result=(result*p)%mod;
p=p*p%mod;
n/=2;
}
return result;
}
__int64 every(__int64 p,__int64 n)
{
if(n==0)
return 1;
if(n%2)
return (every(p,n/2)*(1+get(p,n/2+1)))%mod;
else
return (every(p,n/2-1)*(1+get(p,n/2+1))+get(p,n/2))%mod;
}
int main()
{
int p[size],n[size];
int i;
int A,B;
int ans=1;
while(cin >> A >> B)
{
int k=0;
for(i=2; i*i<=A;)
{
if(!(A%i))
{
p[k]=i;
n[k]=0;
while(!(A%i))
{
n[k]++;
A/=i;
}
k++;
}
if(i==2)
i++;
else
i+=2;
}
if(A!=1)
{
p[k]=A;
n[k++]=1;
}
for(i=0; i<k; i++)
ans=(ans*(every(p[i],n[i]*B))%mod)%mod;
cout << ans << endl;
}
return 0;
}