답안 #702582

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
702582 2023-02-24T13:33:02 Z boris_mihov 메기 농장 (IOI22_fish) C++17
67 / 100
1000 ms 137252 KB
#include "fish.h"
#include <algorithm>
#include <iostream>
#include <cassert>
#include <numeric>
#include <vector>

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
 
typedef long long llong;
const int MAXN = 100000 + 10;
const int MAXM = 600000 + 10;
 
struct Position
{
    int y;
    int idx;
    llong in;
    llong left;
    llong right;
 
    Position(int _y, int _idx, llong _in, llong _left, llong _right)
    {
        y = _y;
        idx = _idx;
        left = _left;
        right = _right;
        in = _in;
    }
};
 
int cnt;
struct SegmentTree
{
    llong tree[4*MAXM];
    SegmentTree()
    {
        std::fill(tree, tree + 4*MAXM, (llong)-1e18);
    }
 
    void update(int l, int r, int node, int queryIdx, llong value)
    {
        if (l == r)
        {
            tree[node] = value;
            return;
        }
 
        int mid = (l + r) / 2;
        if (queryIdx <= mid) update(l, mid, 2*node, queryIdx, value);
        else update(mid + 1, r, 2*node + 1, queryIdx, value);
        tree[node] = std::max(tree[2*node], tree[2*node + 1]);
    }
 
    llong query(int l, int r, int node, int queryL, int queryR)
    {
        if (queryL <= l && r <= queryR)
        {
            return tree[node];
        }
 
        llong ans = -1e18;
        int mid = (l + r) / 2;
        if (queryL <= mid) ans = std::max(ans, query(l, mid, 2*node, queryL, queryR));
        if (mid + 1 <= queryR) ans = std::max(ans, query(mid + 1, r, 2*node + 1, queryL, queryR));
        return ans; 
    }
 
    void update(int pos, llong value)
    {
        update(1, cnt, 1, pos, value);
    }
 
    llong query(int l, int r)
    {
        return query(1, cnt, 1, l, r);
    }
};
 
int n, m;
llong dp[MAXM][2];
std::vector <Position> pos[MAXN];
std::vector <Position> posUncleared[MAXN];
std::vector <std::pair <int,int>> fish[MAXN];
SegmentTree LR, minusL, minusIN;
 
llong max_weights(int N, int M, std::vector <int> X, std::vector <int> Y, std::vector <int> W) 
{
    n = N; m = M;   
    for (int i = 0 ; i < m ; ++i)
    {
        fish[X[i] + 1].emplace_back(Y[i] + 1, W[i]);
    }
 
    for (int x = 1 ; x <= n ; ++x)
    {
        std::sort(fish[x].begin(), fish[x].end());
        for (const auto &[y, w] : fish[x])
        {
            if (x != 1)
            {
                posUncleared[x - 1].push_back({y, 0, 0LL, 0LL, 0LL});
            }
 
            if (x != n)
            {
                posUncleared[x + 1].push_back({y, 0, 0LL, 0LL, 0LL});
            }
        }
    }
 
    for (int x = 1 ; x <= n ; ++x)
    {
        std::sort(posUncleared[x].begin(), posUncleared[x].end(), [&](Position a, Position b)
        {
            return a.y < b.y;
        });
        
        for (Position p : posUncleared[x])
        {
            if (!pos[x].empty() && pos[x].back().y == p.y)
            {
                continue;
            }
 
            pos[x].push_back(p);
        }
 
        int ptrL = 0;
        int ptrR = 0;
        int ptrIN = 0;
        llong inSum = 0;
        llong leftSum = 0;
        llong rightSum = 0;
        for (Position &p : pos[x])
        {
            while (ptrL < fish[x - 1].size() && fish[x - 1][ptrL].first <= p.y)
            {
                leftSum += fish[x - 1][ptrL].second;
                ptrL++;
            }
 
            while (ptrR < fish[x + 1].size() && fish[x + 1][ptrR].first <= p.y)
            {
                rightSum += fish[x + 1][ptrR].second;
                ptrR++;
            }
 
            while (ptrIN < fish[x].size() && fish[x][ptrIN].first <= p.y)
            {
                inSum += fish[x][ptrIN].second;
                ptrIN++;
            }
 
            p.in = inSum;
            p.left = leftSum;
            p.right = rightSum;
        }
    }
    
    for (int x = 1 ; x <= n ; ++x)
    {
        for (Position &p : pos[x])
        {
            p.idx = ++cnt;
        }
    }

    for (int x = n ; x >= 1 ; --x)
    {
        for (int type = 0 ; type < 2 ; ++type)
        {
            for (const Position &curr : pos[x])
            {
                if (x == n) continue;
                int l = -1, r = pos[x + 1].size(), mid;
                while (l < r - 1)
                {
                    mid = (l + r) / 2;
                    if (pos[x + 1][mid].y < curr.y) l = mid;
                    else r = mid;
                }
 
                if (l >= 0)
                {
                    dp[curr.idx][type] = std::max(dp[curr.idx][type], minusIN.query(pos[x + 1][0].idx, pos[x + 1][l].idx));
                }
 
                if (r < pos[x + 1].size() && type == 0)
                {
                    dp[curr.idx][type] = std::max(dp[curr.idx][type], LR.query(pos[x + 1][r].idx, pos[x + 1].back().idx) - curr.in - curr.right);
                }
 
                if (x + 2 <= n)
                {
                    l = -1;
                    r = pos[x + 2].size();
                    while (l < r - 1)
                    {
                        mid = (l + r) / 2;
                        if (pos[x + 2][mid].y < curr.y) l = mid;
                        else r = mid;
                    }
 
                    if (l >= 0)
                    {
                        dp[curr.idx][type] = std::max(dp[curr.idx][type], minusL.query(pos[x + 2][0].idx, pos[x + 2][l].idx));
                    }
 
                    if (r < pos[x + 2].size())
                    {
                        dp[curr.idx][type] = std::max(dp[curr.idx][type], LR.query(pos[x + 2][r].idx, pos[x + 2].back().idx) - curr.right);
                    }
                }
 
                int firstIdx = pos[x].back().idx + 1;
                if (x + 1 <= n && !pos[x + 1].empty())
                {
                    firstIdx = pos[x + 1].back().idx + 1;
                }
 
                if (x + 2 <= n && !pos[x + 2].empty())
                {
                    firstIdx = pos[x + 2].back().idx + 1;
                }
 
                if (firstIdx <= cnt)
                {
                    dp[curr.idx][type] = std::max(dp[curr.idx][type], LR.query(firstIdx, cnt));
                }
            }

            for (const Position &curr : pos[x])
            {
                minusIN.update(curr.idx, dp[curr.idx][1] - curr.in + curr.right);
                LR.update(curr.idx, dp[curr.idx][0] + curr.left + curr.right);
                minusL.update(curr.idx, dp[curr.idx][0] + curr.right);
            }
        }
    }
 
    return LR.query(1, cnt);
}

Compilation message

fish.cpp: In function 'llong max_weights(int, int, std::vector<int>, std::vector<int>, std::vector<int>)':
fish.cpp:138:25: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  138 |             while (ptrL < fish[x - 1].size() && fish[x - 1][ptrL].first <= p.y)
      |                    ~~~~~^~~~~~~~~~~~~~~~~~~~
fish.cpp:144:25: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  144 |             while (ptrR < fish[x + 1].size() && fish[x + 1][ptrR].first <= p.y)
      |                    ~~~~~^~~~~~~~~~~~~~~~~~~~
fish.cpp:150:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  150 |             while (ptrIN < fish[x].size() && fish[x][ptrIN].first <= p.y)
      |                    ~~~~~~^~~~~~~~~~~~~~~~
fish.cpp:190:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Position>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  190 |                 if (r < pos[x + 1].size() && type == 0)
      |                     ~~^~~~~~~~~~~~~~~~~~~
fish.cpp:211:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Position>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  211 |                     if (r < pos[x + 2].size())
      |                         ~~^~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 102 ms 74820 KB Output is correct
2 Correct 117 ms 76144 KB Output is correct
3 Correct 25 ms 63648 KB Output is correct
4 Correct 26 ms 63700 KB Output is correct
5 Correct 741 ms 123632 KB Output is correct
6 Correct 849 ms 137252 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 24 ms 63684 KB Output is correct
2 Correct 364 ms 87580 KB Output is correct
3 Correct 439 ms 91984 KB Output is correct
4 Correct 99 ms 74900 KB Output is correct
5 Correct 115 ms 76132 KB Output is correct
6 Correct 25 ms 63688 KB Output is correct
7 Correct 24 ms 63700 KB Output is correct
8 Correct 24 ms 63624 KB Output is correct
9 Correct 27 ms 63700 KB Output is correct
10 Correct 26 ms 63716 KB Output is correct
11 Correct 26 ms 63648 KB Output is correct
12 Correct 190 ms 79988 KB Output is correct
13 Correct 217 ms 82408 KB Output is correct
14 Correct 186 ms 76468 KB Output is correct
15 Correct 204 ms 77372 KB Output is correct
16 Correct 159 ms 76536 KB Output is correct
17 Correct 180 ms 77240 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 25 ms 63660 KB Output is correct
2 Correct 25 ms 63708 KB Output is correct
3 Correct 106 ms 74488 KB Output is correct
4 Correct 84 ms 71052 KB Output is correct
5 Correct 167 ms 83188 KB Output is correct
6 Correct 164 ms 83252 KB Output is correct
7 Correct 175 ms 83404 KB Output is correct
8 Correct 176 ms 83180 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 26 ms 63708 KB Output is correct
2 Correct 24 ms 63692 KB Output is correct
3 Correct 25 ms 63620 KB Output is correct
4 Correct 25 ms 63700 KB Output is correct
5 Correct 25 ms 63700 KB Output is correct
6 Correct 27 ms 63684 KB Output is correct
7 Correct 25 ms 63608 KB Output is correct
8 Correct 23 ms 63648 KB Output is correct
9 Correct 26 ms 63684 KB Output is correct
10 Correct 28 ms 64040 KB Output is correct
11 Correct 26 ms 63780 KB Output is correct
12 Correct 27 ms 63848 KB Output is correct
13 Correct 25 ms 63700 KB Output is correct
14 Correct 27 ms 63828 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 26 ms 63708 KB Output is correct
2 Correct 24 ms 63692 KB Output is correct
3 Correct 25 ms 63620 KB Output is correct
4 Correct 25 ms 63700 KB Output is correct
5 Correct 25 ms 63700 KB Output is correct
6 Correct 27 ms 63684 KB Output is correct
7 Correct 25 ms 63608 KB Output is correct
8 Correct 23 ms 63648 KB Output is correct
9 Correct 26 ms 63684 KB Output is correct
10 Correct 28 ms 64040 KB Output is correct
11 Correct 26 ms 63780 KB Output is correct
12 Correct 27 ms 63848 KB Output is correct
13 Correct 25 ms 63700 KB Output is correct
14 Correct 27 ms 63828 KB Output is correct
15 Correct 25 ms 63720 KB Output is correct
16 Correct 30 ms 64036 KB Output is correct
17 Correct 141 ms 71688 KB Output is correct
18 Correct 126 ms 72208 KB Output is correct
19 Correct 122 ms 72864 KB Output is correct
20 Correct 110 ms 72556 KB Output is correct
21 Correct 116 ms 72556 KB Output is correct
22 Correct 207 ms 79308 KB Output is correct
23 Correct 54 ms 65656 KB Output is correct
24 Correct 113 ms 70260 KB Output is correct
25 Correct 27 ms 63972 KB Output is correct
26 Correct 48 ms 65500 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 26 ms 63708 KB Output is correct
2 Correct 24 ms 63692 KB Output is correct
3 Correct 25 ms 63620 KB Output is correct
4 Correct 25 ms 63700 KB Output is correct
5 Correct 25 ms 63700 KB Output is correct
6 Correct 27 ms 63684 KB Output is correct
7 Correct 25 ms 63608 KB Output is correct
8 Correct 23 ms 63648 KB Output is correct
9 Correct 26 ms 63684 KB Output is correct
10 Correct 28 ms 64040 KB Output is correct
11 Correct 26 ms 63780 KB Output is correct
12 Correct 27 ms 63848 KB Output is correct
13 Correct 25 ms 63700 KB Output is correct
14 Correct 27 ms 63828 KB Output is correct
15 Correct 25 ms 63720 KB Output is correct
16 Correct 30 ms 64036 KB Output is correct
17 Correct 141 ms 71688 KB Output is correct
18 Correct 126 ms 72208 KB Output is correct
19 Correct 122 ms 72864 KB Output is correct
20 Correct 110 ms 72556 KB Output is correct
21 Correct 116 ms 72556 KB Output is correct
22 Correct 207 ms 79308 KB Output is correct
23 Correct 54 ms 65656 KB Output is correct
24 Correct 113 ms 70260 KB Output is correct
25 Correct 27 ms 63972 KB Output is correct
26 Correct 48 ms 65500 KB Output is correct
27 Correct 32 ms 64324 KB Output is correct
28 Correct 553 ms 100932 KB Output is correct
29 Correct 875 ms 118552 KB Output is correct
30 Execution timed out 1072 ms 131584 KB Time limit exceeded
31 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 25 ms 63660 KB Output is correct
2 Correct 25 ms 63708 KB Output is correct
3 Correct 106 ms 74488 KB Output is correct
4 Correct 84 ms 71052 KB Output is correct
5 Correct 167 ms 83188 KB Output is correct
6 Correct 164 ms 83252 KB Output is correct
7 Correct 175 ms 83404 KB Output is correct
8 Correct 176 ms 83180 KB Output is correct
9 Correct 292 ms 88036 KB Output is correct
10 Correct 184 ms 80116 KB Output is correct
11 Correct 358 ms 96572 KB Output is correct
12 Correct 25 ms 63600 KB Output is correct
13 Correct 23 ms 63692 KB Output is correct
14 Correct 24 ms 63644 KB Output is correct
15 Correct 24 ms 63716 KB Output is correct
16 Correct 25 ms 63700 KB Output is correct
17 Correct 24 ms 63656 KB Output is correct
18 Correct 27 ms 63692 KB Output is correct
19 Correct 28 ms 63700 KB Output is correct
20 Correct 26 ms 63700 KB Output is correct
21 Correct 27 ms 63700 KB Output is correct
22 Correct 315 ms 87920 KB Output is correct
23 Correct 557 ms 104384 KB Output is correct
24 Correct 608 ms 105512 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 102 ms 74820 KB Output is correct
2 Correct 117 ms 76144 KB Output is correct
3 Correct 25 ms 63648 KB Output is correct
4 Correct 26 ms 63700 KB Output is correct
5 Correct 741 ms 123632 KB Output is correct
6 Correct 849 ms 137252 KB Output is correct
7 Correct 24 ms 63684 KB Output is correct
8 Correct 364 ms 87580 KB Output is correct
9 Correct 439 ms 91984 KB Output is correct
10 Correct 99 ms 74900 KB Output is correct
11 Correct 115 ms 76132 KB Output is correct
12 Correct 25 ms 63688 KB Output is correct
13 Correct 24 ms 63700 KB Output is correct
14 Correct 24 ms 63624 KB Output is correct
15 Correct 27 ms 63700 KB Output is correct
16 Correct 26 ms 63716 KB Output is correct
17 Correct 26 ms 63648 KB Output is correct
18 Correct 190 ms 79988 KB Output is correct
19 Correct 217 ms 82408 KB Output is correct
20 Correct 186 ms 76468 KB Output is correct
21 Correct 204 ms 77372 KB Output is correct
22 Correct 159 ms 76536 KB Output is correct
23 Correct 180 ms 77240 KB Output is correct
24 Correct 25 ms 63660 KB Output is correct
25 Correct 25 ms 63708 KB Output is correct
26 Correct 106 ms 74488 KB Output is correct
27 Correct 84 ms 71052 KB Output is correct
28 Correct 167 ms 83188 KB Output is correct
29 Correct 164 ms 83252 KB Output is correct
30 Correct 175 ms 83404 KB Output is correct
31 Correct 176 ms 83180 KB Output is correct
32 Correct 26 ms 63708 KB Output is correct
33 Correct 24 ms 63692 KB Output is correct
34 Correct 25 ms 63620 KB Output is correct
35 Correct 25 ms 63700 KB Output is correct
36 Correct 25 ms 63700 KB Output is correct
37 Correct 27 ms 63684 KB Output is correct
38 Correct 25 ms 63608 KB Output is correct
39 Correct 23 ms 63648 KB Output is correct
40 Correct 26 ms 63684 KB Output is correct
41 Correct 28 ms 64040 KB Output is correct
42 Correct 26 ms 63780 KB Output is correct
43 Correct 27 ms 63848 KB Output is correct
44 Correct 25 ms 63700 KB Output is correct
45 Correct 27 ms 63828 KB Output is correct
46 Correct 25 ms 63720 KB Output is correct
47 Correct 30 ms 64036 KB Output is correct
48 Correct 141 ms 71688 KB Output is correct
49 Correct 126 ms 72208 KB Output is correct
50 Correct 122 ms 72864 KB Output is correct
51 Correct 110 ms 72556 KB Output is correct
52 Correct 116 ms 72556 KB Output is correct
53 Correct 207 ms 79308 KB Output is correct
54 Correct 54 ms 65656 KB Output is correct
55 Correct 113 ms 70260 KB Output is correct
56 Correct 27 ms 63972 KB Output is correct
57 Correct 48 ms 65500 KB Output is correct
58 Correct 32 ms 64324 KB Output is correct
59 Correct 553 ms 100932 KB Output is correct
60 Correct 875 ms 118552 KB Output is correct
61 Execution timed out 1072 ms 131584 KB Time limit exceeded
62 Halted 0 ms 0 KB -