Submission #625675

#TimeUsernameProblemLanguageResultExecution timeMemory
625675phathnvCatfish Farm (IOI22_fish)C++17
100 / 100
368 ms61504 KiB
#include "fish.h"

#include <bits/stdc++.h>
using namespace std;

long long max_weights(int n, int m, vector<int> x, vector<int> y, vector<int> w) {
    vector<vector<int>> a(n + 1);
    vector<vector<array<int, 2>>> b(n + 1);
    vector<vector<array<long long, 2>>> dp[2];
    dp[0].resize(n + 1);
    dp[1].resize(n + 1);

    for (int i = 0; i < m; ++i) {
        b[x[i]].push_back({y[i], w[i]});
        if (0 <= x[i] - 1) {
            a[x[i] - 1].push_back(y[i]);
        }
        if (x[i] + 1 < n) {
            a[x[i] + 1].push_back(y[i]);
        }
    }
    for (int i = 0; i <= n; ++i) {
        a[i].push_back(-1);
        sort(a[i].begin(), a[i].end());
        sort(b[i].begin(), b[i].end());
        a[i].resize(unique(a[i].begin(), a[i].end()) - a[i].begin());
    }

    for (int i = 0; i <= n; ++i) {
        for (auto pos : a[i]) {
            dp[0][i].push_back({pos, 0});
            dp[1][i].push_back({pos, 0});
        }

        if (i == 0) {
            continue;
        }

        long long sumW;
        long long best;
        int ptrW, ptrDp;
        vector<array<int, 2>> weights;
        auto pre = dp[0][i - 1];

        // 0
        weights = b[i - 1];
        sumW = 0;
        ptrW = 0;
        for (auto &[h, val]: pre) {
            while (ptrW < (int)weights.size() && h >= weights[ptrW][0]) {
                sumW += weights[ptrW][1];
                ++ptrW;
            }
            val -= sumW;
        }

        sumW = 0;
        ptrW = 0;
        ptrDp = 0;
        best = -1e18;
        for (auto &[h, val]: dp[0][i]) {
            while (ptrW < (int)weights.size() && h >= weights[ptrW][0]) {
                sumW += weights[ptrW][1];
                ++ptrW;
            }
            while (ptrDp < (int)pre.size() && h >= pre[ptrDp][0]) {
                best = max(best, pre[ptrDp][1]);
                ++ptrDp;
            }
            val = sumW + best;
        }

        // 1
        weights = b[i];
        sumW = 0;
        ptrW = 0;
        pre = dp[1][i - 1];
        for (auto &[h, val]: pre) {
            while (ptrW < (int)weights.size() && h >= weights[ptrW][0]) {
                sumW += weights[ptrW][1];
                ++ptrW;
            }
            val += sumW;
        }

        ptrW = (int)weights.size() - 1;
        ptrDp = (int)pre.size() - 1;
        best = -1e18;
        sumW = 0;
        for (auto [h, w] : weights) {
            sumW += w;
        }
        for (int j = (int)dp[1][i].size() - 1; j >= 0; --j) {
            auto &[h, val] = dp[1][i][j];

            while (ptrW >= 0 && h < weights[ptrW][0]) {
                sumW -= weights[ptrW][1];
                --ptrW;
            }
            while (ptrDp >= 0 && h <= pre[ptrDp][0]) {
                best = max(best, pre[ptrDp][1]);
                --ptrDp;
            }
            val = best - sumW;
        }

        // 1->0
        if (i >= 2) {
            weights = b[i - 1];
            sumW = 0;
            ptrW = 0;
            ptrDp = 0;
            best = 0;
            pre = dp[1][i - 2];
            for (auto &[h, val] : dp[0][i]) {
                while (ptrW < (int)weights.size() && h >= weights[ptrW][0]) {
                    sumW += weights[ptrW][1];
                    ++ptrW;
                }
                while (ptrDp < (int)pre.size() && h >= pre[ptrDp][0]) {
                    best = max(best, pre[ptrDp][1]);
                    ++ptrDp;
                }
                val = max(val, best + sumW);
            }

            sumW = 0;
            ptrW = 0;
            for (auto &[h, val] : pre) {
                while (ptrW < (int)weights.size() && h >= weights[ptrW][0]) {
                    sumW += weights[ptrW][1];
                    ++ptrW;
                }
                val += sumW;
            }

            ptrDp = pre.size() - 1;
            best = -1e18;

            for (auto &[h, val] : dp[0][i]) {
                while (ptrDp >= 0 && h <= pre[ptrDp][0]) {
                    best = max(best, pre[ptrDp][1]);
                    --ptrDp;
                }
                val = max(val, best);
            }
        }

        // 0->1
        for (int j = 0; j < (int) dp[0][i].size(); ++j) {
            dp[1][i][j][1] = max(dp[1][i][j][1], dp[0][i][j][1]);
        }
    }

    return dp[1][n][0][1];
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...