题意:给一个正整数k,求lcm((k, 0), (k, 1), ..., (k, k))
解法:在oeis上查了这个序列,得知答案即为lcm(1, 2, ..., k + 1) / (k + 1),而分子有一个递推式,如果k为一个质数x的某次幂,那么ans[k]为ans[k - 1] * m,否则ans[k] = ans[k - 1]。做除法的时候用了逆元,因为取模来着。
代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<time.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define LL long long
using namespace std;
LL ans[1000005];
LL const mod = 1000000007;
bool isprime[1000005];
LL prime[1000005];
map <LL, int> m;
int cnt = 0;
void init()
{
for(int i = 2; i < 1000005; i++)
{
if(!isprime[i])
{
prime[cnt++] = i;
for(int j = i; j < 1000005; j += i)
isprime[j] = 1;
}
}
for(int i = 0; i < cnt; i++)
{
LL tmp = 1LL;
while(tmp * prime[i] < 1000005)
{
tmp *= prime[i];
m[tmp] = prime[i];
}
}
}
LL power(LL a, LL b, LL MOD) {
LL res = 1;
a %= MOD;
while(b) {
if(b & 1) {
res = res * a % MOD;
b--;
}
b >>= 1;
a = a * a % MOD;
}
return res;
}
int main()
{
init();
ans[1] = 1;
for(int i = 2; i < 1000005; i++)
{
if(m.count(i))
{
ans[i] = ans[i - 1] * m[i] % mod;
}
else
ans[i] = ans[i - 1];
}
int T;
while(~scanf("%d", &T))
{
int n;
while(T--)
{
scanf("%d", &n);
printf("%lld\n", ans[n + 1] * power(n + 1, mod - 2, mod) % mod);
}
}
return 0;
}
原文:http://www.cnblogs.com/Apro/p/4758359.html