【LCM从1-n】 HDU 5407 CRB and Candies
题意:计算C(n,0)+...C(n,n)
思路:转化为LCM(1...n)/ n
代码:
#include <cstdio> #include <bitset> using namespace std; typedef long long ll; const int N = 1000000+2; const ll MOD = (ll)1e9 + 7; ll vis[(N+31)/32 + 5]; int pri[5770000], pnum; ll sum[5770000]; bool Get(int i) { int x = i/32, y = i%32; return 1<<y & vis[x]; } void Set(int i) { int x = i/32, y = i%32; vis[x] |= 1<<y; } void get_prime(int n) { pnum = 0; for(int i = 2;i <= n; i++) { if(!Get(i)) pri[pnum++] = i; for(int j = 0;j < pnum; j++) { if(i*pri[j] > n) break; Set(i*pri[j]); if(i%pri[j] == 0) break; } } sum[0] = pri[0]; for(int i = 1;i < pnum; i++) sum[i] = (ll)sum[i-1]*pri[i]%MOD; } int n; bool ok(int cnt, int m) { ll now = 1; for(int i = 0;i < cnt; i++) { now *= pri[m]; if(now > n) return false; } return true; } int bin(int cnt) { int l = 0, r = pnum-1, ret = -1; while(l <= r) { int mid = l+r>>1; ll now = 1; if(ok(cnt, mid)) { ret = mid; l = mid+1; } else r = mid-1; } return ret; } ll inv[1000007]; int main() { get_prime(1000002); inv[1] = 1; for (int i = 2; i < 1000007; ++i) inv[i] = (MOD-MOD/i)*inv[MOD%i]%MOD; int t, cas = 1; scanf("%d", &t); while (t-- > 0) { scanf("%d", &n); ll ans = 1; int cur = 1; ++n; while(true) { int ret = bin(cur); if(ret == -1) break; ans = (ll)ans*sum[ret]%MOD; cur++; } ans = (ll)ans * inv[n] % MOD; printf("%I64d\n", ans); } return 0; }