QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#267217#4585. Greedy KnapsackNYCU_Yamada#WA 166ms120640kbC++206.5kb2023-11-27 02:22:452023-11-27 02:22:45

Judging History

你现在查看的是最新测评结果

  • [2023-11-27 02:22:45]
  • 评测
  • 测评结果:WA
  • 用时:166ms
  • 内存:120640kb
  • [2023-11-27 02:22:45]
  • 提交

answer

#ifndef Yamada
#define Yamada
#include Yamada __FILE__ Yamada

const int INF = LLONG_MAX >> 2;
const int maxc = 1 << 17;
const int lgmx = 17 + 1;

void solve() {
    int N, T; cin >> N >> T;
    
    vector<int> cost(N+1, 0), val(N+1, 0);
    for (int i = 1; i <= N; ++i) cin >> cost[i];
    for (int i = 1; i <= N; ++i) cin >> val [i];
    
    vector<int> lvl(N+1, 0);
    for (int i = 1; i <= N; ++i) lvl[i] = __lg(cost[i]);
    
    vector precost(lgmx, vector<int>(N+1, 0));
    vector preval (lgmx, vector<int>(N+1, 0));
    vector small  (lgmx, vector<int>(N+1, 0));
    vector large  (lgmx, vector<int>(N+1, 0));
    
    for (int i = 1; i <= N; ++i) {
        for (int lay = 0; lay < lgmx; ++lay) {
            if (lay >= lvl[i]) {
                precost[lay][i] = cost[i];
                preval [lay][i] = val [i];
                small  [lay][i] = cost[i];
            }
            precost[lay][i] += precost[lay][i-1];
            preval [lay][i] += preval [lay][i-1];
            small  [lay][i] += small  [lay][i-1];
            large[lay][i] = (lay == lvl[i]+1 ? small[lay][i-1] + cost[i] : INF);
        }
    }
    
    int global_ans = 0;
    int meowmeow = min(maxc, T);
    vector<vector<tuple<int, int, int>>> queries(lgmx);
    
    function<void(int, int, int, int)> query = [&](int _ans, int _r, int _p, int _M) {
        if (_r < 0) { chmax(global_ans, _ans); return; }
        
        queries[_r].eb(_ans, _p, _M);
        if (SZ(queries[_r]) != meowmeow) return;
        
        sort(ALL(queries[_r]), [](const auto &t1, const auto &t2) {
            return get<1>(t1) > get<1>(t2); /// p decreasing
        });
        
        deque<pii> deq; /// (val, pos)
        
        int last_pos = N;
        for (const int r = _r; auto [ans, p, M] : queries[_r]) {
            
            while (last_pos > p) {
                while (SZ(deq) and large[r][last_pos] <= deq[0].first) deq.pf();
                deq.ef(large[r][last_pos], last_pos);
                --last_pos;
            }
            
            // cerr << "\u001b[33m";
            // cerr << "(r, p, M): (" << r << ", " << p << ", " << M << ")" << "\n";
            // cerr << "\u001b[0m";
            
            if (p == N) { query(ans, r-1, p, M); continue; }
            
            M += precost[r][p];
            
            int pos_large = rend(deq) - upper_bound(RALL(deq), pii{M, N+1});
            // cerr << "? " << pos_large << "\n";
            if (pos_large < SZ(deq) and lvl[deq[pos_large].second] == r + 1) {
                /// pick (p, pos_large], one item in row r+1 ///
                pos_large = deq[pos_large].second;
                query(
                    ans + preval[r][pos_large] - preval[r][p] + val[pos_large],
                    r - 1,
                    pos_large,
                    M - precost[r][pos_large] - cost[pos_large]
                );
                continue;
            }
            
            int pos_small = upper_bound(ALL(small[r]), M) - begin(small[r]) - 1;
            assert(pos_small >= p);
            query(
                ans + preval[r][pos_small] - preval[r][p],
                r - 1,
                pos_small,
                M - precost[r][pos_small]
            );
            
        }
    };
    
    for (int t = T-meowmeow+1; t <= T; ++t) query(0, lgmx-1, 0, t);
    cout << global_ans << "\n";
}

void solve_old() {
    int N, T; cin >> N >> T;
    
    vector<int> cost(N+1, 0), val(N+1, 0);
    for (int i = 1; i <= N; ++i) cin >> cost[i];
    for (int i = 1; i <= N; ++i) cin >> val [i];
    
    vector<int> lvl(N+1, 0);
    for (int i = 1; i <= N; ++i) lvl[i] = __lg(cost[i]);
    
    vector precost(lgmx, vector<int>(N+1, 0));
    vector preval (lgmx, vector<int>(N+1, 0));
    vector small  (lgmx, vector<int>(N+1, 0));
    vector large  (lgmx, vector<int>(N+1, 0));
    
    for (int i = 1; i <= N; ++i) {
        for (int lay = 0; lay < lgmx; ++lay) {
            if (lay >= lvl[i]) {
                precost[lay][i] = cost[i];
                preval [lay][i] = val [i];
                small  [lay][i] = cost[i];
            }
            precost[lay][i] += precost[lay][i-1];
            preval [lay][i] += preval [lay][i-1];
            small  [lay][i] += small  [lay][i-1];
            large[lay][i] = small[lay][i-1] + cost[i];
        }
    }
    for (int lay = 0; lay < lgmx; ++lay) {
        for (int i = N; i >= 1; --i) {
            chmin(large[lay][i-1], large[lay][i]);
        }
    }
    
    function<int(int, int, int)> query = [&](int r, int p, int M) -> int {
        if (r < 0) return 0;
        
        // cerr << "\u001b[33m";
        // cerr << "(r, p, M): (" << r << ", " << p << ", " << M << ")" << "\n";
        // cerr << "\u001b[0m";
        
        M += precost[r][p];
        
        int pos_large = upper_bound(ALL(large[r]), M) - begin(large[r]) - 1;
        if (pos_large > p and lvl[pos_large] == r + 1) {
            /// pick (p, pos_large], one item in row r+1 ///
            return preval[r][pos_large] - preval[r][p] + val[pos_large]
                   + query(r-1, pos_large, M - precost[r][pos_large] - cost[pos_large]);
        }
        
        int pos_small = upper_bound(ALL(small[r]), M) - begin(small[r]) - 1;
        // assert(pos_small >= p);
        return preval[r][pos_small] - preval[r][p]
               + query(r-1, pos_small, M - precost[r][pos_small]);
    };
    
    int ans = 0;
    for (int t = max(T-maxc, int(1)); t <= T; ++t) {
        chmax(ans, query(lgmx-1, 0, t));
    }
    cout << ans << "\n";
}

signed main() {
    IOS();
    int t = 1; // cin >> t;
    for (int i = 1; i <= t; ++i) solve();
    return 0;
}

#else

#ifdef local
#define _GLIBCXX_DEBUG 1
#endif
#include <bits/stdc++.h>
using namespace std;

#define int int64_t
using pii = pair<int, int>;
template <typename T> using MaxHeap = std::priority_queue<T>;
template <typename T> using MinHeap = std::priority_queue<T, vector<T>, greater<T>>;

#define SZ(a) ((int)(a).size())
#define ALL(a) begin(a), end(a)
#define RALL(a) rbegin(a), rend(a)
#define ee emplace
#define eb emplace_back
#define ef emplace_front
#define pb pop_back
#define pf pop_front

#ifdef local
#define IOS() void()
#else
#define IOS() ios_base::sync_with_stdio(0), cin.tie(0);
#endif

template <typename U, typename V> bool chmin(U &u, V v) {return (u > v ? u = v, 1 : 0);}
template <typename U, typename V> bool chmax(U &u, V v) {return (u < v ? u = v, 1 : 0);}

#endif

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3532kb

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: 69ms
memory: 61308kb

input:

5 10000000000
10 1 2 3 4
30 2 15 7 11

output:

65

result:

ok single line: '65'

Test #3:

score: 0
Accepted
time: 0ms
memory: 3544kb

input:

5 20
4 9 5 1 3
203 175 131 218 304

output:

900

result:

ok single line: '900'

Test #4:

score: 0
Accepted
time: 0ms
memory: 3516kb

input:

1 1
1
1

output:

1

result:

ok single line: '1'

Test #5:

score: -100
Wrong Answer
time: 166ms
memory: 120640kb

input:

100000 200000
100000 99998 99996 99994 99992 99990 99988 99986 99984 99982 99980 99978 99976 99974 99972 99970 99968 99966 99964 99962 99960 99958 99956 99954 99952 99950 99948 99946 99944 99942 99940 99938 99936 99934 99932 99930 99928 99926 99924 99922 99920 99918 99916 99914 99912 99910 99908 999...

output:

20

result:

wrong answer 1st lines differ - expected: '100002', found: '20'