class Solution {
public:
typedef long long ll;
ll gcd(ll a,ll b){
return b == 0?a:gcd(b,a%b);
}
ll lcm(ll a,ll b){
ll t = gcd(a,b);
return a / t * b;
}
int bitcount(int v){
int res = 0;
while(v){
if(v & 1)res++;
v >>= 1;
}
return res;
}
ll findKthSmallest(vector<int>& coins, int k) {
ll l = k - 1,r = *min_element(coins.begin(),coins.end()) * (ll)k,n = coins.size();
// 计算小等于 mid的整数中,有几个整数能被集合里至少一种元素整除
function<bool(ll mid)> check = [&](ll mid)->bool{
ll res = 0;
// 容斥原理,枚举所有子集
for(int i = 1;i < 1 << n;i++){
ll v = 1;
for(int j = 0;j < n;j++){
if((i >> j) & 1){
v = lcm(v,coins[j]);
if(v > mid) break;
}
}
//奇正偶负
res += (bitcount(i) % 2 == 0?-1:1) * (mid / v);
}
return res >= k;
};
while(l < r){
ll mid = (l + r) >>1;
if(check(mid)){
r = mid;
}else l = mid + 1;
}
return l;
}
};
容斥原理练习
最新推荐文章于 2024-04-29 09:26:43 发布