题意:求LCM (C(N,0),C(N,1),...,C(N,N)),LCM是最小公倍数的意思,C函数是组合数。
分析:先上出题人的解题报告
好吧,数论一点都不懂,只明白f (n + 1)意思是前n+1个数的最小公倍数,求法解释参考HDOJ 1019,2028
这个结论暂时不知道怎么推出来的,那么就是剩下1/(n+1) 逆元的求法了
代码:
/************************************************ * Author :Running_Time * Created Time :2015-8-21 14:52:39 * File Name :B.cpp ************************************************/ #include <cstdio> #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cmath> #include <string> #include <vector> #include <queue> #include <deque> #include <stack> #include <list> #include <map> #include <set> #include <bitset> #include <cstdlib> #include <ctime> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 typedef long long ll; const int N = 1e6 + 10; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; ll f[N]; int p[N]; bool ok(int n) { int t = p[n]; while (n % t == 0 && n > 1) n /= t; return n == 1; } void seive(int n) { for (int i=1; i<=n; ++i) p[i] = i; for (int i=2; i<=n; ++i) { if (p[i] == i) { for (int j=2*i; j<=n; j+=i) p[j] = i; } } } ll pow_mod(int a, int x, int p) { ll ret = 1; while (x) { if (x & 1) ret = ret * a % p; a = a * 1ll * a % p; x >>= 1; } return ret; } ll Inv(int a) { return pow_mod (a, MOD - 2, MOD); } void solve(void) { seive (1000010); f[0] = 1; for (int i=1; i<=1000010; ++i) { if (ok (i)) { f[i] = f[i-1] * p[i] % MOD; } else f[i] = f[i-1]; } } int main(void) { solve (); int T; scanf ("%d", &T); while (T--) { int n; scanf ("%d", &n); printf ("%I64d ", f[n+1] * Inv (n + 1) % MOD); } return 0; }