题目连接:
http://www.lightoj.com/volume_showproblem.php?problem=1054
题目大意:
给出n,m,问n^m的所有因子之和是多少?
解题思路:
补充知识:
1:对于一个数字n=p1^t1+p2^t2+p3^t3+.........+pn^tn。求n因子和等价于n所有因子的子集所对应值相加之和—(p1^0+p1^1+p1^2+......+p1^t1)*(p2^0+p2^1+......+p2^t2)*.....*(pn^0+pn^1+......+pn^tn).
2:等比数列求和公式:
3:除法取余:(a/b)%p == a%(b%p)/b%p;
a/b%p == a*b^(p-2)%p;(当p是素数) 证明:有费马小定理可知:p是素数,(b,p) = 1, b^(p-1)%p == 1,a/b%p == a/b*1%p == a/b*b^(p-1)% == a*b^(p-2)%p.
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int mod = 1000000007; 5 const int maxn = 7000; 6 typedef long long LL; 7 int isprime[maxn], prime[maxn*10]; 8 LL sum, k; 9 10 void Isprime () 11 {//筛选出需要的素数 12 int i, j; 13 for (i=2, k=0; i<70000; i++) 14 if (!prime[i]) 15 { 16 isprime[k ++] = i; 17 for (j=i; j<70000; j+=i) 18 prime[j] = 1; 19 } 20 // printf ("%d ", k); 21 } 22 23 LL Pow (LL x, LL y) 24 {//快速幂求x^y 25 LL num = 1; 26 while (y) 27 { 28 if (y % 2) 29 num = (num * x) % mod; 30 x = (x * x) % mod; 31 y /= 2; 32 } 33 return num; 34 } 35 LL solve (LL x, LL y) 36 { 37 LL num; 38 num = (Pow(x, y) - 1); 39 num = (num * Pow(x-1, mod-2)) % mod; 40 return (num + mod) % mod; 41 } 42 43 int main () 44 { 45 LL t, n, m, l = 0; 46 Isprime (); 47 scanf ("%lld", &t); 48 while (t --) 49 { 50 scanf ("%lld %lld", &n, &m); 51 LL a, b, i; 52 i = 0; 53 sum = 1; 54 while (i < k) 55 { 56 if (1 == n) 57 break; 58 a = b = 0;//统计还有的素数因子和因子的个数 59 if (n % isprime[i] == 0) 60 { 61 a = isprime[i]; 62 while (n % isprime[i] == 0) 63 { 64 b ++; 65 n /= isprime[i]; 66 } 67 sum = (sum * solve(a, b*m+1) ) % mod; 68 } 69 i ++; 70 71 } 72 if (n != 1) 73 sum = (sum * solve(n, m+1)) % mod; 74 printf ("Case %lld: %lld ", ++l, sum); 75 } 76 return 0; 77 }