poj 1845 二分
题意:求A^B的所有因数的和 (0 <= A,B <= 50000000), 结果对9901取余。
分析:设A=p1^r1*p2^r2*...*pn^rn,则A^B=p1^(B*r1) * p2^(B*r2) * ... * pn^(B*rn)。
A^B的因数之和为:(1+p1+p1^2+...+p1^(B*r1)) * (1+p2+p2^2+...+p2^(B*r2)) *... * (1+pn+pn^2+...+pn^(B*rn));
等比数列求和公式:(p^n-1) / (p-1) p-1可能为9901的倍数,即gcd(p-1,9901) !=1,不能用逆元。
也不能用公式a/b%m = a%(bm)/b,因为bm容易越界。
令f(n)=1+p+p^2+...+p^n,
n为奇数时,f(n) = (1+p+p^2+...+p^(n/2)) * (1 + p^(n/2+1)) = f(n/2) * (1 + p^(n/2+1)),
n为偶数时,f(n) = f(n-1) + p^n。
可以递归求解
int mod = 9901; int a, b, s; int pri[]={2,3,5,7,11,13,17....7079}; LL modexp(int a, int b) { LL ans = 1; LL t = a; while(b) { if(b & 1) ans = ans * t % mod; t = t * t % mod; b >>= 1; } return ans; } int cal(int p, int n){//计算1+p+p^2+...+p^n if(!n) return 1; if(n&1) return cal(p, n/2)*(1+modexp(p, n/2+1)) % mod; else return (cal(p, n-1) + modexp(p, n)) % mod; } void solve(int n){ s = 1; for(int i = 0; pri[i] * pri[i] <= n; i++){ int cnt = 0; while(n % pri[i] == 0) {//找到质因子 n /= pri[i]; cnt++; } if(cnt) s = s * cal(pri[i],cnt*b) % mod; } if(n > 1) s = s * cal(n,b) % mod; } int main(){ #ifndef ONLINE_JUDGE //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif cin>>a>>b; if(!a){cout<<0<<endl;return 0;} solve(a); cout<<s<<endl; return 0; }