【CF912E】Prime Game(meet in the middle)

【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;
}
原文地址:https://www.cnblogs.com/cjyyb/p/9687227.html