从1到s选出k个数 他们的最大公约数大于1 求方案数
容斥 S(1)-S(2)+S(3) S(x)为选出k个数的公因子个数为x的数量
#include <cstdio> #include <cmath> #include <cstring> using namespace std; typedef long long LL; const int maxn = 55; int prime[maxn], vis[maxn]; int n, m; int get_primes(int n) { int m = sqrt(n+0.5), c = 0; for(int i = 2; i <= n; i++) if(!vis[i]) { prime[c++] = i; for(int j = i*2; j <= n; j += i) { vis[j] = 1; } } return c; } LL cm(int n, int m) { LL ans = 1; for(int i = 1; i <= m; i++) { ans *= (LL)n--; ans /= (LL)i; } return ans; } void dfs(int i, int x, int k, int m, LL& ans, int c) { if(i == c) { if(!k) return; if(k&1) ans += cm(m/x, n); else ans -= cm(m/x, n); return; } dfs(i+1, x*prime[i], k+1, m, ans, c); dfs(i+1, x, k, m, ans, c); } LL cal(int c) { LL ans = 0; dfs(0, 1, 0, m, ans, c); if(ans > 10000) ans = 10000; return ans; } int main() { int c = get_primes(50); //printf("%d\n", c); while(scanf("%d %d", &n, &m) != EOF) { printf("%lld\n", cal(c)); } return 0; }
时间: 2024-12-29 04:58:45