打败魔人布欧以后,孙悟空收了n个徒弟,每个徒弟战斗力各不相同。他教导所有的徒弟和体术,合体后战斗力为原战斗力相乘。任何两个徒弟都可以合体,所以一共有n*(n-1)/2种合体徒弟。有一天,他想考验一下孙悟天战斗力如何,希望在所有n*(n-1)/2种合体徒弟中选择战斗力第k高的,与孙悟天对战。可是孙悟空徒弟太多了,他已然懵逼,于是找到了你,请你帮他找到对的人。
打败魔人布欧以后,孙悟空收了n个徒弟,每个徒弟战斗力各不相同。他教导所有的徒弟和体术,合体后战斗力为原战斗力相乘。任何两个徒弟都可以合体,所以一共有n*(n-1)/2种合体徒弟。有一天,他想考验一下孙悟天战斗力如何,希望在所有n*(n-1)/2种合体徒弟中选择战斗力第k高的,与孙悟天对战。可是孙悟空徒弟太多了,他已然懵逼,于是找到了你,请你帮他找到对的人。
第一行两个int。徒弟数量:n <= 1*10^6;战斗力排名:k <= n*(n-1)/2
第二行空格分隔n个int,表示每个徒弟的战斗力。
战斗力排名k的合体徒弟战斗力。
5 2 1 3 4 5 9
36
// 二分答案,然后再去找答案。思路和9月1号pdd最后一道类似。
#include <iostream>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#include <vector>
#include <list>
#include <stack>
#include <string>
#include <set>
#include <queue>
#include <climits>
#include <unordered_set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <unordered_map>
#include <map>
using namespace std;
typedef long long LL;
const int mod = 1e9+7;
using namespace std;
const int inf = 0x7f7f7f7f;
#define _for(i,l,r) for(int i=(l);i<(r);i++)
LL data[1000005];
int main() {
LL n,k;
scanf("%lld%lld",&n,&k);
_for(i,0,n){
scanf("%lld",&data[i]);
}
sort(data,data + n);
LL l = data[0] * data[1], r = data[n - 1] * data[n - 2];
k = n * (n - 1) / 2 - k + 1;
while(r > l){
LL mid = (l + r) / 2;
LL cnt = 0;
for(LL i = n - 1;i>=0 ;i--){
LL tmp = mid / data[i];
if(i) {
LL index = upper_bound(data, data + i, tmp) - data;
cnt += index;
}
}
if(cnt >= k){
r = mid;
}else{
l = mid + 1;
}
}
LL t = LLONG_MIN;
// cout << " l : "<< l << endl;
for(LL i = 1;i<n;i++){
LL tmp = l / data[i];
LL index = upper_bound(data, data + i, tmp) - data;
t = max(t,data[i] * data[index - 1]);
}
cout << t << endl;
return 0;
} #include <bits/stdc++.h>
using namespace std;
long long check(vector<long long>& att, long long& mid, long long k, long long n)
{
long long below = 0;
long long num = 0;
long long same_p = 0;
long long min_val = att[n - 1] * att[n - 1] * 2;
for (long long i = 0; i < n; i++)
{
long long pos = upper_bound(att.begin() + i + 1, att.end(), mid / att[i]) - att.begin();
num += att.size() - pos;
if (pos == att.size())
continue;
long long minu = att[pos] * att[i] - mid;
if (minu < min_val)
{
min_val = minu;
below = att[pos] * att[i];
same_p = 0;
}
if(minu == min_val)
same_p++;
}
if(k == num || (num > k && num-same_p < k))
{
mid = below;
num = k;
}
return num;
}
int main() {
long long n,k;
vector<long long> att;
scanf("%lld %lld", &n, &k);
long long tmp;
for (long long i = 0; i < n; i++)
{
scanf("%lld", &tmp);
att.push_back(tmp);
}
sort(att.begin(), att.end());
long long lo = att[0] * att[1];
long long hi = att[n - 1] * att[n - 2];
long long ans;
while (lo <= hi)
{
long long mid = (lo + hi) >> 1;
long long num = check(att, mid, k, n);
if (num == k)
{
ans = mid;
break;
}
if (num > k)
{
lo = mid + 1;
}
else
hi = mid - 1;
}
printf("%lld\n", ans);
return 0;
}
AC
n, k = list(map(int, input().split())) nums = list(map(int, input().split())) nums.sort() def upper_bound(nums, target): low, high = 0, len(nums)-1 pos = len(nums) while low<high: mid=(low+high) // 2 if nums[mid]<=target: low = mid+1 else:#> high = mid pos = high if nums[low]>target: pos = low return pos def Smaller(x): cnt = 0 for i in range(len(nums) - 1): cnt += len(nums[i+1:]) - upper_bound(nums[i+1:], x // nums[i]) if cnt >= k: return True return False low, high = nums[0] * nums[1], nums[-1] * nums[-2] while low < high: mid = (low + high) // 2 if Smaller(mid): low = mid + 1 else: high = mid print(high)
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
long k = scan.nextLong();
long[] power = new long[n];
for(int i=0;i<n;i++){
power[i] = scan.nextLong();
}
Arrays.sort(power);
long l = 1,r = power[n-1]*power[n-2],mid = 0;
while(l<r){
mid = (l+r+1)/2;
long cnt = 0;
int left = 0, right = n-1;
while(left<right && cnt<k){
while(power[left]*power[right]<mid) left++;
cnt+=Math.max(right-left,0);
right--;
}
if(cnt>=k) l=mid;
else r = mid-1;
}
System.out.println(l);
}
} #include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
long n, k;
scanf("%ld%ld", &n, &k);
vector<long> A(n);
for (int i = 0; i < n; ++i)
scanf("%ld", &A[i]);
sort(A.begin(), A.end());
long left = 1, right = A[n-1]*A[n-2];
while (left<=right)
{
long mid = (left+right)/2;
long count = 0;
int i = 0, j = n-1;
while (i < j && count < k)
{
while (i < j && A[i]*A[j]<mid) i++;
count += j-i;
j--;
}
if (count >= k)
left = mid+1;
else
right = mid-1;
}
printf("%ld\n", right);
return 0;
}
n,k = map(int,input().split()) t = list(map(int,input().split())) print(sorted([t[i]*t[j] for i in range(n-1) for j in range(i+1,n)])[-k])
nk = list(map(int,input().split())) n = nk[0] k = nk[1] fight = sorted(list(map(int,input().split()))) res = [] for i in range(0, n-1): for j in range(i+1, n): num = fight[i] * fight[j] res.append(num) res = sorted(res, reverse = True) print(res[k - 1]) 65%,我觉得不能用暴力求解,应该是找到第K个直接结束循环
nk = list(map(int,input().split())) n = nk[0] k = nk[1] fight = sorted(list(map(int,input().split()))) res = [] for i in range(0, n): for j in range(1, i): num = fight[i] * fight[j] res.append(num) res = sorted(res, reverse = True) print(res[k - 1])