제출 #292002

#제출 시각아이디문제언어결과실행 시간메모리
292002Diuven로봇 골프 (ROI19_golf)C++11
100 / 100
1743 ms71372 KiB
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <assert.h>
#include <algorithm>
#include <iomanip>
#include <time.h>
#include <math.h>
#include <bitset>
#include <ext/pb_ds/assoc_container.hpp>

using namespace __gnu_pbds;

#pragma comment(linker, "/STACK:256000000")

using namespace std;

typedef long long int ll;
typedef long double ld;
typedef gp_hash_table<int, int> table;

const int INF = 1000 * 1000 * 1000 + 21;
const ll LLINF = (1ll << 60) + 5;
const int MOD = 998244353;

const int MAX_N = 1000 * 1000 + 228;

struct point {
    int x;
    int y;
};

bool operator<(const point& a, const point& b) {
    return a.x + a.y > b.x + b.y || (a.x + a.y == b.x + b.y && a.x - a.y < b.x - b.y);
}

bool operator==(const point& a, const point& b) {
    return a.x == b.x && a.y == b.y;
}

ll n, m;
int k;
map<pair<int, int>, int> costs;
vector<point> points[2];
vector<int> diags[2];
table dp;

inline int calc_cost(int x, int ptr1, int ptr2, map<pair<int, int>, int>::iterator it) {
    if (x == n - 1) {
        return 0;
    } else if (it != costs.end()) {
        return it->second;
    } else {
        int ans = -INF;
        if (1 <= ptr1 && ptr1 <= n + n - 1) {
            ans = max(ans, dp[ptr1]);
        } else {
            ans = max(ans, 0);
        }
        if (1 <= ptr2 && ptr2 <= n + n - 1) {
            ans = max(ans, dp[ptr2]);
        } else {
            ans = max(ans, 0);
        }

        return ans;
    }
}

int main() {
#ifdef CH_EGOR
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#else
    //freopen("", "r", stdin);
    //freopen("", "w", stdout);
#endif

    scanf("%lld%lld%d", &n, &m, &k);
    n = max(n, m); // magic

    for (int i = -2; i <= k; ++i) {
        int x, y, c;
        if (i == -2) {
            x = 0;
            y = 1;
            c = 0;
        } else if (i == -1) {
            x = 1;
            y = 0;
            c = 0;
        } else if (i == 0) {
            x = 0;
            y = 0;
            c = 0;
        } else {
            scanf("%d%d%d", &x, &y, &c);
            --x; --y;
            costs[{x, y}] = c;
        }
        for (int dx = 0; dx <= 2; ++dx) {
            for (int dy = 0; dy <= 2; ++dy) {
                int gox = x - dx;
                int goy = y - dy;
                if (gox >= 0 && goy >= 0 && dx + dy <= 2) {
                    points[(gox + goy) & 1].push_back({gox, goy});
                    diags[(gox + goy) & 1].push_back(gox + goy);

                    if (gox - goy >= 0) {
                        points[(gox + goy) & 1].push_back({gox - goy, 0});
                        diags[(gox + goy) & 1].push_back({gox - goy});
                    } else {
                        points[(gox + goy) & 1].push_back({0, goy - gox});
                        diags[(gox + goy) & 1].push_back(goy - gox);
                    }

                    if (gox - goy >= 2) {
                        points[(gox + goy) & 1].push_back({gox - goy - 2, 0});
                        diags[(gox + goy) & 1].push_back({gox - goy - 2});
                    } else if (gox - goy <= -2) {
                        points[(gox + goy) & 1].push_back({0, goy - gox - 2});
                        diags[(gox + goy) & 1].push_back(goy - gox - 2);
                    }
                }
            }
        }
    }

    int ans = 0;
    for (int i = 0; i < 2; ++i) {
        dp.clear();
        sort(points[i].begin(), points[i].end());
        points[i].resize(unique(points[i].begin(), points[i].end()) - points[i].begin());
        sort(diags[i].begin(), diags[i].end());
        diags[i].resize(unique(diags[i].begin(), diags[i].end()) - diags[i].begin());
        reverse(diags[i].begin(), diags[i].end());

        int cur_add = 0;
        int points_ptr = 0;
        for (int j = 0; j < (int)diags[i].size(); ++j) {
            int lf = 0;
            int rf = 0;

            if (diags[i][j] >= n - 1) {
                lf = n - ((n + n - 2) - diags[i][j]);
                rf = n + ((n + n - 2) - diags[i][j]);
            } else {
                lf = n - diags[i][j];
                rf = n + diags[i][j];
            }

            if (j != 0) {
                ans = (ans + (ll)(diags[i][j - 1] - diags[i][j] - 1) / 2ll * cur_add) % MOD;
            }

            if (diags[i][j] < n - 1) {
                if (dp.find(lf - 2) != dp.end()) {
                    cur_add = (cur_add - dp[lf - 2]) % MOD;
                }
                if (dp.find(rf + 2) != dp.end()) {
                    cur_add = (cur_add - dp[rf + 2]) % MOD;
                }
            }

            vector<pair<int, int>> new_vals;
            for ( ;
                points_ptr < (int)points[i].size() && points[i][points_ptr].x + points[i][points_ptr].y >= diags[i][j];
                ++points_ptr) {

                int x = points[i][points_ptr].x;
                int y = points[i][points_ptr].y;

                auto it = costs.find({x, y});
                int rl_val = min(
                    it != costs.end() ? it->second : calc_cost(x, n + x - y + 2, n + x - y, costs.find({x + 1, y})),
                    it != costs.end() ? it->second : calc_cost(y, n + x - y - 2, n + x - y, costs.find({x, y + 1}))
                );

                if (lf <= n + x - y && n + x - y <= rf) {
                    new_vals.push_back({n + x - y, rl_val});
                }
            }

            for (int i = 0; i < (int)new_vals.size(); ++i) {
                cur_add = (cur_add - dp[new_vals[i].first]) % MOD;
                cur_add = (cur_add + new_vals[i].second) % MOD;
                dp[new_vals[i].first] = new_vals[i].second;
            }

            /*
            cerr << "Now " << diags[i][j] << endl;
            for (int i = lf; i <= rf; i += 2) {
                cerr << dp[i] << " ";
            }
            cerr << endl;
            */

            ans = (ans + cur_add) % MOD;
        }
    }

    if (ans < 0) {
        ans += MOD;
    }

    printf("%d\n", ans);

    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

golf.cpp:22: warning: ignoring #pragma comment  [-Wunknown-pragmas]
   22 | #pragma comment(linker, "/STACK:256000000")
      | 
golf.cpp: In function 'int main()':
golf.cpp:87:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   87 |     scanf("%lld%lld%d", &n, &m, &k);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
golf.cpp:105:18: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  105 |             scanf("%d%d%d", &x, &y, &c);
      |             ~~~~~^~~~~~~~~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...