Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define int long long
- using namespace std;
- const int BS = 333;
- const int INF = 1e18;
- int Ceil(int a, int b) { return a / b + (a % b > 0); }
- struct CHT {
- deque<tuple<int, int, int>> stk;
- void InsertLine(int a, int b) {
- int p = -INF;
- while (stk.size()) {
- auto [pp, ap, bp] = stk.back();
- if (ap == a) p = bp < b ? INF : -INF;
- else p = Ceil(b - bp, ap - a);
- if (p > pp) break;
- stk.pop_back();
- }
- if (p != INF) stk.emplace_back(p, a, b);
- }
- int EvalMin(int x) {
- if (stk.empty()) return INF;
- while ((int)stk.size() > 1 && get<0>(stk[1]) <= x)
- stk.pop_front();
- auto [_, a, b] = stk.front();
- return a * x + b;
- }
- };
- int32_t main() {
- int n, S; cin >> n >> S;
- vector<pair<int, int>> v(n);
- for (int i = 0; i < n; ++i)
- cin >> v[i].second;
- for (int i = 0; i < n; ++i)
- cin >> v[i].first;
- sort(v.rbegin(), v.rend());
- vector<CHT> chts(n / BS + 1);
- vector<int> da(n / BS + 1), db(da);
- vector<int> a(n), b(n);
- for (int i = 0; i < n; ++i)
- tie(a[i], b[i]) = v[i];
- auto rebuild = [&](int bi) {
- chts[bi].stk.clear();
- int l = bi * BS, r = min(n, l + BS);
- for (int i = l; i < r; ++i) {
- if (b[i] < INF)
- chts[bi].InsertLine(a[i], b[i]);
- }
- };
- for (int i = 0; i < n; i += BS)
- rebuild(i / BS);
- int ans = 0;
- for (int i = 0; i < n; ++i) {
- pair<int, int> best = {INF, -1};
- for (int j = 0; j < (int)chts.size(); ++j) {
- int now = chts[j].EvalMin(da[j]) + db[j];
- best = min(best, make_pair(now, j));
- }
- assert(best.second != -1);
- int bi = best.second;
- int l = bi * BS, r = min(n, l + BS);
- int choose = -1;
- for (int i = l; i < r; ++i) {
- b[i] += db[bi] + da[bi] * a[i];
- if (b[i] == best.first)
- choose = i;
- }
- da[bi] = db[bi] = 0;
- assert(choose != -1);
- cerr << "choose: " << choose + 1 << " with cost: " << best.first << endl;
- if (b[choose] <= S) {
- S -= b[choose];
- ans += 1;
- } else break;
- for (int i = 0; i < bi; ++i)
- db[i] += a[choose];
- for (int i = l; i < r; ++i) {
- if (i < choose) b[i] += a[choose];
- else b[i] += a[i];
- }
- for (int i = bi + 1; i < (int)da.size(); ++i)
- da[i] += 1;
- a[choose] = 0; b[choose] = INF;
- rebuild(bi);
- }
- cout << ans << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement