【CF912E】Prime Game(meet in the middle)
题面
CF
懒得翻译了。
题解
一眼题。
(meet in the middle)分别爆算所有可行的两组质数,然后二分答案,(two-pointers)扫一下就好了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
int n,m;ll K;
int p[20],t1,t2;
vector<ll> s1,s2;
void dfs1(int x,ll s)
{
if(x>n){s1.push_back(s);++t1;return;}
for(ll w=1;;w*=p[x]){dfs1(x+2,s*w);if(1e18/p[x]<w*s)break;}
}
void dfs2(int x,ll s)
{
if(x>n){s2.push_back(s);++t2;return;}
for(ll w=1;;w*=p[x]){dfs2(x+2,s*w);if(1e18/p[x]<w*s)break;}
}
int main()
{
scanf("%d",&n);m=(n+1)/2;
s1.push_back(0);s2.push_back(0);
for(int i=1;i<=n;++i)scanf("%d",&p[i]);
sort(&p[1],&p[n+1]);dfs1(1,1);dfs2(2,1);
sort(&s1[1],&s1[t1+1]);sort(&s2[1],&s2[t2+1]);
scanf("%I64d",&K);
ll l=1,r=1e18,ret;
while(l<=r)
{
ll mid=(l+r)>>1,tot=0;
for(int i=1,p=t2;i<=t1;++i,tot+=p)
while(p&&mid/s1[i]<s2[p])--p;
if(tot<K)l=mid+1;
else ret=mid,r=mid-1;
}
cout<<ret<<endl;
return 0;
}