無恥的廣告 更好的閱讀體驗~
\(N = 2 \times 10^5\),考慮二分答案。
所以,答案有單調性嗎?或者說,可以二分嗎?
當然!如果 \(x = k\) 時可以滿足條件,那麼 \(x = k - 1\) 時顯然只會更少(上面取 \(\min\) 的基本都沒變,變了的去了更少的),一樣能滿足條件。
\(\operatorname{check}\) 函式怎麼寫?掃一遍嘛,時間複雜度 \(O(n)\),鑑於後面是 \(\log\) 級別的複雜度這裡就算暴力掃也超不了。
這樣我們只需要考慮二分的上下界就好了。最低直接讓 \(x = 0\) 好了,最高肯定不會超過 \(A\) 陣列的總和(超了那還了得?),就以此為界二分吧!
等等,我們漏了一個很重要的情況!那就是——無!解!
啥時候無解啊?
按照題意,需要的錢數最大也只有 \(\sum_{i = 1}^{n} A_i\) 這麼多,如果這還不到 \(m\),那麼 \(x\) 自然可以隨便取,反正錢數都沒它啥事兒……
還有一點,上面這一大堆東西時間複雜度到底是多少呢?
\(\Theta(N \log (\min_x, \max_x))\),其中 \(\min_x\) 表示 \(x\) 的下界,\(\max_x\) 表示 \(x\) 的上界。感覺會超?注意時間限制是 2s !拿計算器摁一下,最大值(兩項都取到最大)大概是 \(9.5 \times 10^7\),不會超~
然後就真的結束了……
ACCode:
/*Code by Leo2011*/
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define EPS 1e-8
#define FOR(i, l, r) for (ll(i) = (l); (i) <= (r); ++(i))
#define log printf
#define IOS \
ios::sync_with_stdio(false); \
cin.tie(nullptr); \
cout.tie(nullptr);
using namespace std;
typedef __int128 i128;
typedef long long ll;
typedef pair<ll, ll> PII;
const ll N = 2e5 + 10;
bool flg = 0;
ll m, n, w, a[N], sum;
template <typename T>
inline T read() {
T sum = 0, fl = 1;
char ch = getchar();
for (; !isdigit(ch); ch = getchar())
if (ch == '-') fl = -1;
for (; isdigit(ch); ch = getchar()) sum = sum * 10 + ch - '0';
return sum * fl;
}
template <typename T>
inline void write(T x) {
if (x < 0) {
putchar('-'), write<T>(-x);
return;
}
static T sta[35];
ll top = 0;
do { sta[top++] = x % 10, x /= 10; } while (x);
while (top) putchar(sta[--top] + 48);
}
inline bool chk(ll q) {
ll sum = 0;
FOR(i, 1, n) {
sum += min(q, a[i]);
if (sum > m) return 0;
}
return sum <= m;
}
int main() {
scanf("%lld%lld", &n, &m);
FOR(i, 1, n) scanf("%lld", &a[i]), sum += a[i];
w = m / n;
if (sum <= m) {
log("infinite");
return 0;
}
ll l = 0, r = sum, ret = -1;
while (l <= r) {
ll mid = (l + r) >> 1;
if (chk(mid)) {
ret = mid;
l = mid + 1;
} else r = mid - 1;
}
log("%lld\n", ret);
return 0;
}
AC 記錄~
理解萬歲!