답안 #678828

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
678828 2023-01-06T16:21:02 Z pls33 메기 농장 (IOI22_fish) C++17
9 / 100
1000 ms 52796 KB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#ifndef _AAAAAAAAA
#include "fish.h"
#endif

using namespace std;
using namespace __gnu_pbds;

#pragma region dalykai
using p32 = pair<int, int>;
using p32u = pair<uint32_t, uint32_t>;
using p64 = pair<int64_t, int64_t>;
using p64u = pair<uint64_t, uint64_t>;
using vi16 = vector<int16_t>;
using vi16u = vector<uint16_t>;
using vi32 = vector<int>;
using vi32u = vector<uint32_t>;
using vi64 = vector<int64_t>;
using vi64u = vector<uint64_t>;
using vp32 = vector<p32>;
using vp32u = vector<p32u>;
using vp64 = vector<p64>;
using vp64u = vector<p64u>;
using vvi32 = vector<vi32>;
using vvi32u = vector<vi32u>;
using vvi64 = vector<vi64>;
using vvi64u = vector<vi64u>;
using vvp32 = vector<vp32>;
using vvp32u = vector<vp32u>;
using vvp64 = vector<vp64>;
using vvp64u = vector<vp64u>;
#pragma endregion

using map_t = gp_hash_table<int64_t, int64_t>;
const auto __comp = [](p64 a, p64 b)
{
    return a.first < b.first;
};

struct node_t
{
    int64_t val;
    p32 range;
    node_t *left, *right;

    node_t(p32 r)
    {
        val = 0;
        range = r;
        left = nullptr;
        right = nullptr;
    }

    void update()
    {
        if (!right || range.second - range.first == 1)
        {
            return;
        }

        val = max(left->val, right->val);
    }

    void expand()
    {
        if (range.second - range.first == 1 || right)
        {
            return;
        }

        int mid = (range.first + range.second) / 2;
        left = new node_t({range.first, mid});
        right = new node_t({mid, range.second});
    }

    int contains(p32 query)
    {
        if (query.first >= range.second || query.second <= range.first)
        {
            return 0;
        }

        if (range.first >= query.first && range.second <= query.second)
        {
            return 1;
        }

        return 2;
    }
};

void update(node_t *node, int64_t val, p32 dest)
{
    if (!node || !node->contains(dest))
    {
        return;
    }

    if (node->contains(dest) == 1)
    {
        node->val = max(node->val, val);
        return;
    }

    node->expand();
    update(node->left, val, dest);
    update(node->right, val, dest);
    node->update();
}

int64_t query(node_t *node, p32 dest)
{
    if (!node || !node->contains(dest))
    {
        return 0;
    }

    if (node->contains(dest) == 1)
    {
        return node->val;
    }

    return max(query(node->left, dest),
               query(node->right, dest));
}

void assign_max(int64_t val, int64_t &v)
{
    v = max(v, val);
}

int64_t weight_sum(int l, int r, vp64 &prefix)
{
    if (l == -1 || !prefix.size() || r < prefix[0].first)
    {
        return 0;
    }

    auto hi = lower_bound(prefix.begin(), prefix.end(), p64{r, INT64_MAX}, __comp);
    if (hi == prefix.end())
    {
        hi--;
    }

    int64_t sum = hi->second;
    if (l)
    {
        auto lo = lower_bound(prefix.begin(), prefix.end(), p64{l - 1, INT64_MAX}, __comp);
        if (lo != hi)
        {
            sum -= lo->second;
        }
    }

    return sum;
}

int64_t new_weight(p32 lhs, p32 rhs, vvp64 &prefix)
{
    int64_t left = rhs.first > 0
                       ? weight_sum(0, rhs.second, prefix[rhs.first - 1])
                       : 0;

    int64_t right = (rhs.first + 1 < (int)prefix.size())
                        ? weight_sum(0, rhs.second, prefix[rhs.first + 1])
                        : 0;

    if (lhs.first == -1)
    {
        return left + right;
    }

    if (rhs.first - lhs.first > 2)
    {
        return left + right;
    }

    if (rhs.first - lhs.first == 2)
    {
        if (lhs.second >= rhs.second)
        {
            return right;
        }
        left -= weight_sum(0, lhs.second, prefix[rhs.first - 1]);
        return left + right;
    }

    if (lhs.second > rhs.second)
    {
        left = -weight_sum(0, rhs.second, prefix[rhs.first]);
        return left + right;
    }

    left -= weight_sum(0, lhs.second, prefix[rhs.first]) +
            weight_sum(0, lhs.second, prefix[rhs.first - 1]);
    return left + right;
}

long long max_weights(int N, int M,
                      std::vector<int> X,
                      std::vector<int> Y,
                      std::vector<int> W)
{
    vp32 fish;

    vvp64 prefix(N);
    for (int i = 0; i < M; i++)
    {
        prefix[X[i]].emplace_back(Y[i], W[i]);
        if (X[i])
        {
            fish.push_back({X[i] - 1, Y[i]});
        }
        if (X[i] < N - 1)
        {
            fish.push_back({X[i] + 1, Y[i]});
        }
    }

    for (auto &row : prefix)
    {
        sort(row.begin(), row.end(), __comp);
        for (int i = 1; i < (int)row.size(); i++)
        {
            row[i].second += row[i - 1].second;
        }
    }

    sort(fish.begin(), fish.end());
    auto it = unique(fish.begin(), fish.end());
    fish.erase(it, fish.end());

    map_t decrease({}, {}, {}, {}, {1ULL << 17});
    map_t increase({}, {}, {}, {}, {1ULL << 17});
    vp32 check;

    node_t *fish_count = new node_t({0, N});
    for (auto &f : fish)
    {
        int64_t initial = new_weight(p32(-1, -1), f, prefix);
        if (f.first > 2)
        {
            initial += query(fish_count, {0, f.first - 2});
        }

        auto &f_inc = increase[f.first * N + f.second];
        auto &f_dec = decrease[f.first * N + f.second];

        assign_max(initial, f_inc);
        assign_max(initial, f_dec);
        check.push_back(f);
        for (int cur = (int)check.size() - 2; cur >= 0; cur--)
        {
            auto &[i, j] = check[cur];
            auto &inc = increase[i * N + j];
            auto &dec = decrease[i * N + j];

            if (f.first - i > 3)
            {
                break;
            }

            if (i == f.first)
            {
                continue;
            }
            int64_t prev = new_weight(p32(i, j), f, prefix);
            if (i == f.first - 1)
            {
                if (j < f.second)
                {
                    assign_max(prev + inc, f_inc);
                }
                else
                {
                    assign_max(prev + dec, f_dec);
                }
            }
            else
            {
                prev += max(inc, dec);
                assign_max(prev, f_inc);
                assign_max(prev, f_dec);
            }
        }

        update(fish_count,
               max(f_inc, f_dec),
               {f.first, f.first + 1});
    }

    return fish_count->val;
}

#ifdef _AAAAAAAAA
int main()
{
    freopen("fish.in", "r", stdin);
#ifndef __linux__
    atexit([]()
           {
        freopen("con", "r", stdin);
        system("pause"); });
#endif

    int N, M;
    assert(2 == scanf("%d %d", &N, &M));

    std::vector<int> X(M), Y(M), W(M);
    for (int i = 0; i < M; ++i)
    {
        assert(3 == scanf("%d %d %d", &X[i], &Y[i], &W[i]));
    }

    long long result = max_weights(N, M, X, Y, W);
    printf("%lld\n", result);
    return 0;
}
#endif

Compilation message

fish.cpp:11: warning: ignoring '#pragma region dalykai' [-Wunknown-pragmas]
   11 | #pragma region dalykai
      | 
fish.cpp:34: warning: ignoring '#pragma endregion ' [-Wunknown-pragmas]
   34 | #pragma endregion
      |
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1071 ms 14652 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 6356 KB Output is correct
2 Execution timed out 1080 ms 20116 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 8788 KB Output is correct
2 Correct 5 ms 8748 KB Output is correct
3 Correct 87 ms 19316 KB Output is correct
4 Correct 56 ms 17128 KB Output is correct
5 Correct 160 ms 36460 KB Output is correct
6 Correct 162 ms 36232 KB Output is correct
7 Correct 163 ms 36376 KB Output is correct
8 Correct 160 ms 36328 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 6356 KB Output is correct
2 Correct 3 ms 6444 KB Output is correct
3 Correct 3 ms 6356 KB Output is correct
4 Correct 3 ms 6356 KB Output is correct
5 Correct 3 ms 6484 KB Output is correct
6 Correct 4 ms 6356 KB Output is correct
7 Correct 3 ms 6356 KB Output is correct
8 Correct 3 ms 6356 KB Output is correct
9 Correct 6 ms 6484 KB Output is correct
10 Correct 7 ms 6712 KB Output is correct
11 Incorrect 5 ms 6484 KB 1st lines differ - on the 1st token, expected: '278622587073', found: '278348685419'
12 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 6356 KB Output is correct
2 Correct 3 ms 6444 KB Output is correct
3 Correct 3 ms 6356 KB Output is correct
4 Correct 3 ms 6356 KB Output is correct
5 Correct 3 ms 6484 KB Output is correct
6 Correct 4 ms 6356 KB Output is correct
7 Correct 3 ms 6356 KB Output is correct
8 Correct 3 ms 6356 KB Output is correct
9 Correct 6 ms 6484 KB Output is correct
10 Correct 7 ms 6712 KB Output is correct
11 Incorrect 5 ms 6484 KB 1st lines differ - on the 1st token, expected: '278622587073', found: '278348685419'
12 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 6356 KB Output is correct
2 Correct 3 ms 6444 KB Output is correct
3 Correct 3 ms 6356 KB Output is correct
4 Correct 3 ms 6356 KB Output is correct
5 Correct 3 ms 6484 KB Output is correct
6 Correct 4 ms 6356 KB Output is correct
7 Correct 3 ms 6356 KB Output is correct
8 Correct 3 ms 6356 KB Output is correct
9 Correct 6 ms 6484 KB Output is correct
10 Correct 7 ms 6712 KB Output is correct
11 Incorrect 5 ms 6484 KB 1st lines differ - on the 1st token, expected: '278622587073', found: '278348685419'
12 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 8788 KB Output is correct
2 Correct 5 ms 8748 KB Output is correct
3 Correct 87 ms 19316 KB Output is correct
4 Correct 56 ms 17128 KB Output is correct
5 Correct 160 ms 36460 KB Output is correct
6 Correct 162 ms 36232 KB Output is correct
7 Correct 163 ms 36376 KB Output is correct
8 Correct 160 ms 36328 KB Output is correct
9 Correct 276 ms 52796 KB Output is correct
10 Incorrect 162 ms 30488 KB 1st lines differ - on the 1st token, expected: '36454348383152', found: '36452445968580'
11 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1071 ms 14652 KB Time limit exceeded
2 Halted 0 ms 0 KB -