poj1845(二分快速求等比数列模M和)
Sumdiv
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 17039 | Accepted: 4280 |
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
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <stdlib.h> using namespace std; #define MOD 9901 typedef long long ll; //a^b%mod 快速幂 long long Quk_Mul(long long a,long long b,long long mod) { long long qsum=1; while(b) { if(b&1) qsum=(qsum*a)%mod; b>>=1; a=(a*a)%mod; } return qsum; }//二分计算1+a+a^2+...+a^b long long Bin_Find(int a,long long b) { if(b==0) return 1; if(b%2==0) { return ( Bin_Find(a, b/2-1)+Bin_Find(a, b/2-1)*Quk_Mul(a, b/2+1, MOD)+Quk_Mul(a, b/2, MOD) )%MOD; } else { return ( Bin_Find(a, b/2)+Quk_Mul(a, b/2+1, MOD)*Bin_Find(a, b/2) )%MOD; } } long long GetDivsorSum(int x,int b) { long long sum=1; for(int i=2;i*i<=x;i++) { long long tmp=0; if(x%i == 0) { while(x%i==0) { x/=i; tmp++; } //假设 tmp *= b; sum *= Bin_Find(i,tmp); sum%=MOD; } } if(x>1)//在这里x可能等于 9901 { long long tmp=1; tmp *= b; int i=x; sum *= Bin_Find(i, tmp); sum%=MOD; } return sum; } int main(int argc, const char * argv[]) { int a,b; // for(int i=2;i<9901;i++) // if(9901%i==0) printf("%d\n",i); while(scanf("%d%d",&a,&b)!=EOF) { if(a==0) { printf("0\n"); } else if(b==0) printf("1\n"); else cout<<(GetDivsorSum(a,b)%MOD+MOD)%MOD<<endl; /* long long tmp=1; long long ans=0; for(int i=0;i<b;i++) tmp*=a; for(int j=1;j<=tmp;j++) { if(tmp%j==0) ans=ans+j; ans%=MOD; } cout<<ans<<endl; */ } return 0; }
//求一个数的因子和。因为求逆元不是很方便,所以采用二分求等比数列和