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 }
本文为博主原创文章,未经博主允许不得转载。