题目链接:http://lightoj.com/volume_showproblem.php?problem=1054
题意:给你两个数n和m, 求n^m的所有因子和,结果对1000000007求余;(n和m在int范围内)
和求因子个数有一定的关系,一个数 n 可以表示成 n = p1^a1 * p2^a2 * p3^a3 * ... pk^ak,(其中pi是n的素因子)
那么n的因子和就是 (p1^0+p1^1+p1^2+...+p1^a1)*(p2^0+p2^1+p2^2+...+p2^a2)*...*(pk^0+pk^1+...+pk^ak);
至于为什么可以把这些拆开来想就好了;所以对于每一项我们要求等比数列的和,还有就是除法求余问题运用公式 a/b%mod = a*b^(mod-2);
#include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> typedef long long LL; #define N 100005 using namespace std; const double eps = 1e-6; const LL mod = 1000000007; int f[N], p[N], k = 0; void Prime() { for(int i=2; i<N; i++) { if(!f[i]) p[k++] = i; for(int j=i; j<N; j+=i) f[j] = 1; } } LL Pow(LL a, LL b)/// Calculate: a^b%mod; { LL ans = 1; while(b) { if(b&1) ans = ans*a%mod; a = a*a%mod; b >>= 1; } return ans; } ///a/b%mod = a*b^(mod-2)%mod; LL Sn(LL q, LL n)/// Calculate: (q^n-1)/(q-1)%mod; { LL ans = Pow(q, n); ans = (ans-1) * Pow(q-1, mod-2) % mod; return (ans+mod)%mod;///因为上面出现了-1所以可能变成负数; } int main() { Prime(); int T, t = 1; LL n, m; scanf("%d", &T); while(T--) { scanf("%lld %lld", &n, &m); LL ans = 1; for(int i=0; i<k && (LL)p[i]*p[i]<=n; i++) { if(n%p[i])continue; LL cnt = 0; while(n%p[i] == 0) { cnt ++; n /= p[i]; } cnt = cnt*m+1; LL ret = Sn(p[i], cnt); ans = ans*ret%mod; } if(n>1) ans = ans*Sn(n, m+1)%mod; printf("Case %d: %lld ", t++, ans); } return 0; }