AT_abc362_c [ABC362C] Transportation Expenses

worker2011發表於2024-08-03

無恥的廣告 更好的閱讀體驗~


\(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 記錄~

理解萬歲!