hdu5407 CRB and Candies

令f(n) = lcm((n, 0), (n, 1),..., (n, n)),

g(n) = lcm(1, 2,.., n)。

则有结论:f(n) = g(n + 1) / (n + 1)(证明过程参阅:http://arxiv.org/pdf/0906.2295v2.pdf)。

待求的是ans = f(n) % mod

= (g(n + 1) / (n + 1)) % mod

= (g(n + 1) % mod * Inverse(n + 1) % mod) % mod。

其中Inverse(n)表示n的关于mod的乘法逆元,即满足Inverse(n) * n % mod = 1。

由费尔马小定理,amod-1%mod = 1, 于是 a * amod -2 % mod = 1。

则Inverse(n) = amod-2 %mod(mod 为素数),逆元唯一。

这样用快速幂很快计算一个数的乘法逆元,下面需要计算g(n)。

有以下结论g(n) = 

g(n - 1) * p (如果存在质数p和整数k,满足n = pk)(1),

g(n - 1) (否则)。

我们需要预处理出一个对于每个整数其可能对应的p的数组以快速计算g(n)。

所有的素数存在唯一的p等于其本身和k=1满足式(1)。

对于任一整数可以写成素数幂的乘积的形式,因此可以用当前素数往后更新。

 

http://acm.hdu.edu.cn/showproblem.php?pid=5407

 

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 
 5 using namespace std;
 6 typedef __int64 LL;
 7 
 8 const int maxn = 1e6 + 10;
 9 const int mod = 1e9 + 7;
10 
11 int n;
12 LL f[maxn], g[maxn];
13 
14 LL power(LL a, LL p){
15     LL ans = 1;
16     a %= mod;
17     while(p){
18         if(p & 1){
19             ans = (ans * a) % mod;
20         }
21         p >>= 1;
22         a = (a * a) % mod;
23     }
24     return ans;
25 }
26 
27 LL Inverse(LL num){
28     return power(num, mod - 2);
29 }
30 
31 void solve(){
32     LL ans = f[n + 1] * Inverse(n + 1) % mod;
33     printf("%I64d\n", ans);
34 }
35 
36 bool check(int num){
37     int d = g[num];
38     while(num % d == 0 && num > 1) num /= d;
39     return num == 1;
40 }
41 
42 void init(){
43     for(int i = 1; i < maxn; i++) g[i] = i;
44     for(int i = 2; i < maxn; i++){
45         if(g[i] == i){
46             for(int j = i + i; j < maxn; j += i){
47                 g[j] = i;
48             }
49         }
50     }
51     f[0] = 1;
52     for(int i = 1; i < maxn; i++){
53         if(check(i)) f[i] = f[i - 1] * g[i] % mod;
54         else f[i] = f[i - 1];
55     }
56 }
57 
58 int main(){
59     init();
60     int T;
61     scanf("%d", &T);
62     while(T--){
63         scanf("%d", &n);
64         solve();
65     }
66     return 0;
67 }
View Code

 

posted @ 2015-08-22 00:48  astoninfer  阅读(273)  评论(0编辑  收藏  举报