QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#177517 | #4585. Greedy Knapsack | ucup-team288 | RE | 0ms | 3648kb | C++20 | 4.8kb | 2023-09-13 01:03:34 | 2023-09-13 01:03:35 |
Judging History
answer
#include <bits/stdc++.h>
#undef KEV
using namespace std;
using i64 = long long;
using ll = long long;
#define pb emplace_back
#define X first
#define Y second
#define AI(i) begin(i), end(i)
template<class T> bool chmax(T &a, T b) { return a < b && (a = b, true);}
template<class T> bool chmin(T &a, T b) { return b < a && (a = b, true);}
#ifdef KEV
#define DE(args...) kout("[ " + string(#args) + " ] = ", args)
void kout() { cerr << endl; }
template<class T, class ...U> void kout(T a, U ...b) { cerr << a << ' ', kout(b...); }
template<class T> void debug(T l, T r) { while (l != r) cerr << *l++ << " \n"[l==r]; }
#else
#define DE(...) 0
#define debug(...) 0
#endif
const int MAX_N = 300010, MAX_K = 40;
ll add_v[MAX_K], add_w[MAX_K];
// [ l, r, value ]
// small comes out
set< tuple<ll,ll,ll> > pq[MAX_K];
//priority_queue< tuple<ll,ll,ll>, vector<tuple<ll,ll,ll>>, greater<>> > pq[MAX_K];
int safe_lg(ll v) {
return v == 0 ? -1 : __lg(v);
}
ll res;
void put(ll l, ll r, ll v) {
chmax(res, v);
//chmax(l, 1ll);
if (l > r) return;
int k = safe_lg(l);
assert(k == safe_lg(r));
ll nl = l - add_w[k], nr = r - add_w[k], nv = v - add_v[k];
while (true) {
auto it = pq[k].lower_bound({nl, -1, -1});
if (it != end(pq[k])) {
auto [pl, pr, pv] = *it;
if (pl == nr + 1 && pv == nv) {
nr = pr;
pq[k].erase(it);
}
if (nr >= pl) {
if (nv >= pv) {
pq[k].erase(it);
if (pr > nr)
pq[k].insert({nr+1, pr, pv});
} else {
if (nr > pr)
put(pr+1 + add_w[k], nr + add_w[k], v);
nr = pl-1;
}
} else break;
} else break;
}
{
auto it = pq[k].lower_bound({nl, -1, -1});
if (it != begin(pq[k])) {
--it;
auto [pl, pr, pv] = *it;
if (nl <= pr) {
if (nv >= pv) {
pq[k].erase(it);
if (pl < nl)
pq[k].insert({pl, nl-1, pv});
} else {
nl = pr+1;
}
}
}
}
if (nl <= nr)
pq[k].insert({nl, nr, nv});
}
void chk(int k) {
//DE(k);
while (pq[k].size()) {
auto [_l, _r, _v] = *pq[k].begin();
ll l = _l + add_w[k], r = _r + add_w[k], v = _v + add_v[k];
if (l >= (1ll << k)) break;
//DE(l, r, 1ll << k);
pq[k].erase(pq[k].begin());
if (l == 0) {
chmax(res, v);
if (r > l)
pq[k].insert({_l+1, _r, _v});
continue;
}
int nk = safe_lg(l);
ll nr = min(r, (2ll << nk)-1);
//DE(nr);
put(l, nr, v);
if (nr < r) {
//assert(nr+1-add_w[k] <= _r);
//put(nr+1, r, v);
pq[k].insert({nr+1 - add_w[k], _r, _v});
assert(nr+1 - add_w[k] <= _r);
}
}
}
void obo(int k, ll dv, ll more) {
//DE("obo");
while (pq[k].size()) {
auto [_l, _r, _v] = *pq[k].rbegin();
//DE(_l, _r, _v);
ll l = _l + add_w[k], r = _r + add_w[k], v = _v + add_v[k];
if (r < dv) break;
pq[k].erase(prev(end(pq[k])));
if (r == dv) {
chmax(res, more + v);
if (r > l)
pq[k].insert({_l, _r-1, _v});
continue;
}
int nk = safe_lg(r - dv);
ll nr = r - dv;
ll nl = max(l - dv, 1ll << nk);
put(nl, nr, v + more);
DE(l, r, v, dv, nl, nr);
if (nl != l - dv) {
pq[k].insert({_l, nl+dv-1 - add_w[k], _v});
DE(_l, nl+dv-1 - add_w[k]);
//DE(_l, nl-1-add_w[k]);
assert(_l <= nl+dv-1-add_w[k]);
}
}
}
void dd() {
DE("DD--------------__");
for (int i = 0;i < MAX_K;++i) if (pq[i].size()) {
DE(i);
for (auto [_l, _r, _v] : pq[i]) {
DE(_l+add_w[i], _r+add_w[i], _v+add_v[i]);
}
}
}
ll brute(ll n, ll T, vector<ll> w, vector<ll> v) {
ll ret = 0;
for (int i = 1;i <= T;++i) {
ll cw = 0, cv = 0;
for (int j = 0;j < n;++j)
if (cw + w[j] <= i)
cw += w[j], cv += v[j];
chmax(ret, cv);
}
return ret;
}
random_device rd;
mt19937 gen(rd());
int main() {
ios_base::sync_with_stdio(0), cin.tie(0);
int N;
ll T;
cin >> N >> T;
vector<ll> w(N), v(N);
for (auto &i : w) cin >> i;
for (auto &i : v) cin >> i;
//
// N = 100, T = 5000;
//
//
// vector<ll> w(N), v(N);
// for (auto &i : w) i = gen() % 100 + 1;
// for (auto &i : v) i = gen() % 100 + 1;
//
for (int i = 0;;++i) {
ll l = 1ll << i, r = min(T, (1ll<<(i+1))-1);
put(l, r, 0);
if (r == T) break;
}
for (int i = 0;i < N;++i) {
DE(w[i], v[i]);
int k = safe_lg(w[i]);
obo(k, w[i], v[i]);
for (++k; k < MAX_K;++k) {
add_v[k] += v[i];
add_w[k] += -w[i];
chk(k);
}
//dd();
}
for (int k = 0;k < MAX_K;++k) {
//DE(k);
for (auto [_1, _2, _v] : pq[k])
chmax(res, _v + add_v[k]);
}
cout << res << '\n';
// DE(brute(N, T, w, v));
// cout << N << ' ' << T << '\n';
// for (int i = 0;i < N;++i)
// cout << w[i] << ' ';
// cout << '\n';
// for (int i = 0;i < N;++i)
// cout << v[i] << ' ';
// cout << endl;
//
//assert(res == brute(N, T, w, v));
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3648kb
input:
5 10 10 1 2 3 4 1 1 1 1 1
output:
3
result:
ok single line: '3'
Test #2:
score: 0
Accepted
time: 0ms
memory: 3632kb
input:
5 10000000000 10 1 2 3 4 30 2 15 7 11
output:
65
result:
ok single line: '65'
Test #3:
score: -100
Runtime Error
input:
5 20 4 9 5 1 3 203 175 131 218 304