标签:include using nbsp 二分答案 data turn name vector for
http://codeforces.com/gym/101064/problem/D
题目是给定一个数组,如果两两组合,有C(n, 2)种结果,(找出第一个大于等于第k大的结果)
思路,
二分答案val,判断如下。
先把数组排序。
然后暴力枚举每个数a[i],那么找出第一个大于val - a[i]的,中间的数字和它组合。都是<=val的
统计这些数字的个数,如果大于等于k就是可行解。
hack。
二分答案的时候,明显下界是a[1] + a[2]。上界是a[n] + a[n - 1]
如果用begin = 1。end = 5e10L是错的
begin可以是0
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> const int maxn = 1e5 + 20; LL a[maxn]; map<LL, int>book; LL n, k; bool check(LL val) { LL total = 0; for (int i = 1; i <= n; ++i) { LL dis = val - a[i]; if (val < 2 * a[i]) break; if (dis >= a[n]) { total += n - i; } else { int pos = upper_bound(a + 1, a + 1 + n, dis) - a; total += pos - 1 - i; } if (total >= k) return true; } //// cout << total << endl; // if (total > k) return true; return false; } void work() { IOS; cin >> n >> k; for (int i = 1; i <= n; ++i) { cin >> a[i]; } sort(a + 1, a + 1 + n); // cout << check(7) << endl; LL be = a[1] + a[2]; LL en = a[n] + a[n - 1]; assert(be <= en); // cout << check(0) << endl; while (be <= en) { LL mid = (be + en) >> 1; if (check(mid)) { en = mid - 1; } else be = mid + 1; } // assert(be <= a[n] + a[n - 1]); cout << be << endl; } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }
D. Black Hills golden jewels 二分答案 + 二分判定
标签:include using nbsp 二分答案 data turn name vector for
原文地址:http://www.cnblogs.com/liuweimingcprogram/p/6139749.html