// poj 1845-Sumdiv /* * 数学 * 求 A^B 因子的和模9901 (0 <= A,B <= 50000000) * A可以唯一分解成p1^a1*p2^a2*...*pn^an, * 则 A^B=p1^(a1*B)*p2^(a2*B)*...*pn^(an*B); * sum(A^B的所有约数)=[1+p1+p1^2+...+p1^(a1*B)]*[1+p2+p2^2+...+p2^(a2*B)]*[1+pn+pn^2+...+pn^(an*B)] * 问题变为如何快速求出 (等比数列的和)%9901 * 分治法:1:n为奇数(偶数项)mult_sum(int p,int n)=(1+pow_mod(p,n/2+1))*mult_sum(p,n/2) * n为偶数(奇数项)mult_sum(int p,int n)=pow_mod(p,n/2)+(1+pow_mod(p,n/2+1))*mult_sum(p,n/2-1) * 例如:n=3,则(1+p)+(p^2+p^3)=(1+p)+p^2(1+p). * n=4,则(1+p)+p^2+(p^3+p^4)=(1+p)+p^2+p^3(1+p)。 * 2: 求a^b也是用的分治思想 * !!!构造素因子时如果直接将A除到一会超时 例如:A=2*5242...1(素数) * 判断到sqrt(A)即可 * tle tle wa ac 220k 0ms */ #include <iostream> using namespace std; #define MAX 10000 const int m=9901; long long pow_mod(int a,int n) { if(n==0) return 1; long long x,ans; x=pow_mod(a,n/2); ans=(x*x)%m; if(n&1) ans=(ans*a)%m; return ans; } long long mult_sum(int p,int n) { if(n==0) return 1; if(n&1) return (long long)((1+pow_mod(p,n/2+1))*mult_sum(p,n/2))%m; else return (long long)(pow_mod(p,n/2)+((1+pow_mod(p,n/2+1))*mult_sum(p,n/2-1))%m)%m; } int main() { long long i,k,A,B,sum; cin>>A>>B; for(sum=1,k=0,i=2; i*i<A; ++i){ if(!(A%i)){ while(!(A%i)){ k++; A/=i; } sum=(long long)(sum*mult_sum(i,k*B))%m; k=0; } if(A==1) break; } if(A!=1) //!!! sum=(long long)(sum*mult_sum(A,B))%m; cout<<sum<<endl; return 0; }