标签:
题意:给一个正整数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