题意:
计算(LCM(C(n,0),C(n,1),C(n,2),cdots,C(n,n-1),C(n,n)))
(nle 10^6)
题解:
规律:
(LCM(C(n,0),C(n,1),C(n,2),cdots,C(n,n-1),C(n,n)) = frac{LCM(1,2,3,cdots,,n-1,n,n+1)}{n+1})
令(g(n)=LCM(C(n,0),C(n,1),C(n,2),cdots,C(n,n-1),C(n,n)))
(f(n)=LCM(1,2,3,cdots,,n-1,n))
则(g(n)=frac{f(n+1)}{n+1})
所以问题转化为求解(f(n))
我们只需要知道每一个质数的最高次项是多少即可
如果(n=p^k),且我们已经知道了(f(n-1))那么,到(n)的时候(p)的最高次项必然比之前大了(1),所以(f(n)=f(n-1)*p),否则(f(n)=f(n-1))
(f(n))可以递推得到
[f(n) = egin{cases} f(n-1)*p & n=p^k \ f(n-1) & otherwise end{cases}
]
然后就可以计算(g(n))了
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
typedef long long int LL;
const int MAXN = 1e6+7;
const int MOD = 1e9+7;
LL f[MAXN],inv[MAXN],p[MAXN];
bool npm[MAXN];
vector<LL> prime;
void preprocess(){
for(int i = 2; i < MAXN; i++){
if(!npm[i]) prime.push_back(i);
for(int j = 0; j < (int)prime.size(); j++){
if(i*prime[j]>=MAXN) break;
npm[i*prime[j]] = true;
if(i%prime[j]==0) break;
}
}
fill(begin(p),end(p),1);
inv[1] = 1;
for(int i = 2; i < MAXN; i++) inv[i] = (MOD-MOD/i) * inv[MOD%i] % MOD;
for(LL pm : prime) for(LL x = pm; x < MAXN; x *= pm) p[x] = pm;
f[1] = 1;
for(int i = 2; i < MAXN; i++) f[i] = f[i-1] * p[i] % MOD;
}
int main(){
preprocess();
int T;
for(scanf("%d",&T); T; T--){
int n; scanf("%d",&n);
printf("%I64d
",f[n+1]*inv[n+1]%MOD);
}
return 0;
}