Hdu 5407 CRB and Candies (找规律)

题目链接:

  Hdu 5407 CRB and Candies

题目描述:

  给出一个数n,求lcm(C(n,0),C[n,1],C[n-2]......C[n][n-2],C[n][n-1],C[n][n])%(1e9+7)是多少?

解题思路:

  刚开始的时候各种开脑洞,然后卡题卡的风生水起。最后就上了数列查询这个神奇的网站,竟然被我找到了!!!!就是把题目上给的问题转化为求lcm(1, 2, 3, 4 ...... n-2, n-1, n, n-1) / (n+1),扎扎就打了两个表一个lcm[n],区间[1,n]的最小公倍数,一个C[n],代表pow(n, mod-2),每次查询就变成了O(1)。还是依旧卡的飞起(现在想起,心还是好痛),最后发现lcm数组计算的时候由于lcm的性质限制,并不能lcm[n]=(lcm[n-1]/gcd(lcm[n-1], n)*n)%mod。随后就开始了TLE之旅,然后就在反复计算复杂度,TLE的很迷啊。怎么计算也并不会T啊,最后换了G++就通过了。(扎扎只能说是神题。恩,没错,是神题)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 const int maxn = 1000005;
 9 const int mod = 1000000007;
10 LL lcm[maxn], C[maxn], prim[maxn], cnt;
11 bool mark[maxn];
12 
13 void isprim ()
14 {
15     cnt = 0;
16     for (int i=2; i<maxn; i++)
17         if (mark[i] == false)
18         {
19             prim[cnt++] = i;
20             for (int j=i+i; j<maxn; j+=i)
21                 mark[j] = true;
22         }
23 }
24 LL Pow (LL x, LL n)
25 {
26     LL res = 1;
27     while (n)
28     {
29         if (n % 2)
30             res = (res * x) % mod;
31         x = (x * x) % mod;
32         n /= 2;
33     }
34     return res;
35 }
36 void init ()
37 {
38     for (int i=1; i<maxn; i++)
39         C[i] = Pow(i, mod-2);
40     isprim();
41     for (int i=0; i<cnt; i++)
42     {
43         LL x = prim[i];
44         while (x < maxn)
45         {
46             lcm[x] = prim[i];
47             x *= prim[i];
48         }
49     }
50     lcm[0] = 1;
51     for (int i=1; i<maxn; i++)
52     {
53         if (lcm[i] == 0)
54             lcm[i] = 1;
55         lcm[i] = (lcm[i-1] * lcm[i]) % mod;
56     }
57 }
58 int main ()
59 {
60     int t, n;
61     init ();
62     scanf ("%d", &t);
63     while (t --)
64     {
65         scanf ("%d", &n);
66         printf ("%lld\n", lcm[n+1] * C[n+1] % mod);
67     }
68     return 0;
69 }

 

posted @ 2015-08-21 10:07  罗茜  阅读(344)  评论(0编辑  收藏  举报