链接:点击打开链接
题意:给出含n个数的集合,求第k大的所有 质因子都在这个集合中的数
代码:
#include <map>
#include <stack>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll INF=1e18;
ll a[20];
vector<ll> G[2];
void dfs(ll id,ll sum,ll op,ll en){
ll i;
if(id>en){
if(sum!=1)
G[op].push_back(sum);
return;
}
for(i=0;;i++){
if(i>0&&sum<=INF/a[id])
sum*=a[id];
else if(i!=0)
return;
dfs(id+1,sum,op,en);
}
} //dfs出所有组成的数
ll judge(ll mid){
ll i,j,id=0,ans;
for(i=0;i<G[0].size();i++)
if(G[0][i]<=mid)
id++;
j=0,ans=id;
for(i=id-1;i>=0;i--){ //因为两个集合的数都是递增的,所以
while(j<G[1].size()){ //直接双指针移动一下
if(G[1][j]<=mid/G[0][i])
j++;
else
break;
}
ans+=j;
}
return ans;
}
int main(){
ll i,n,k,l,r,ans,mid;
while(scanf("%I64d",&n)!=EOF){
for(i=1;i<=n;i++)
scanf("%I64d",&a[i]);
scanf("%I64d",&k);
G[0].clear(),G[1].clear();
dfs(1,1,0,min(6ll,n)); //让小的数少分几个,剩下的数一组
dfs(min(6ll,n)+1,1,1,n);
G[0].push_back(1); //在第一组插入1
sort(G[0].begin(),G[0].end());
sort(G[1].begin(),G[1].end());
l=1,r=INF;
while(l<=r){ //直接二分出答案
mid=(l+r)/2;
if(judge(mid)>=k){
r=mid-1;
ans=mid;
}
else
l=mid+1;
}
printf("%I64d\n",ans);
}
return 0;
}