大意:求素因子只含给定素数的第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); }
原文地址:https://www.cnblogs.com/uid001/p/10409960.html
时间: 2024-10-06 05:19:59