Prime Gift CodeForces - 912E (中途相遇)

链接

大意:求素因子只含给定素数的第k大数

先二分答案转为判定x是第几大, 然后分两块合并即可, 按奇偶分块可以优化一下常数

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define pb push_back

using namespace std;
typedef long long ll;

const int N = 2e5+10;
int a[N], b[N], f[N], n, m;
ll k;
vector<ll> s[2];


ll calc(ll x) {
	ll ans = 0;
	int now = 0;
	PER(i,0,s[0].size()-1) {
		while (now<s[1].size()&&s[1][now]<=x/s[0][i]) ++now;
		ans += now;
	}
	return ans;
}

void dfs(int d, int cur, ll now) {
	s[d].pb(now);
	REP(i,cur,*f) if (now<=1e18/f[i]) dfs(d,i,now*f[i]);
}

int main() {
	scanf("%d", &n);
	REP(i,1,n) scanf("%d", a+i);
	sort(a+1,a+1+n);
	scanf("%lld", &k);
	REP(i,1,n) if (i&1) f[++*f] = a[i];
	dfs(0,1,1), *f = 0;
	REP(i,1,n) if (i&1^1) f[++*f] = a[i];
	dfs(1,1,1);
	sort(s[0].begin(),s[0].end());
	sort(s[1].begin(),s[1].end());
	ll l = 1, r = 1e18, ans;
	while (l<=r) {
		int mid = (l+r)/2;
		if (calc(mid)>=k) ans = mid, r = mid-1;
		else l = mid+1;
	}
	printf("%lld\n", ans);
}

猜你喜欢

转载自www.cnblogs.com/uid001/p/10409960.html