이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
// Hallelujah, praise the one who set me free
// Hallelujah, death has lost its grip on me
// You have broken every chain, There's salvation in your name
// Jesus Christ, my living hope
#include <bits/stdc++.h> 
using namespace std;
template <class T>
inline bool mnto(T& a, T b) {return a > b ? a = b, 1 : 0;}
template <class T>
inline bool mxto(T& a, T b) {return a < b ? a = b, 1: 0;}
#define REP(i, s, e) for (int i = s; i < e; i++)
#define RREP(i, s, e) for (int i = s; i >= e; i--)
typedef long long ll;
typedef long double ld;
#define FI first
#define SE second
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef tuple<int, int, int> iii;
#define ALL(_a) _a.begin(), _a.end()
#define SZ(_a) (int) _a.size()
#define pb push_back
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<ii> vii;
typedef vector<iii> viii;
#ifndef DEBUG
#define cerr if (0) cerr
#endif
const int INF = 1000000005;
const ll LINF = 1000000000000000005ll;
const int MAXN = 200005;
int h, w;
int a[MAXN], b[MAXN];
ll ans;
struct node {
    ll num, denom;
    int id;
    bool isrow;
    bool operator<(const node &o) const {
        if (num * o.denom == o.num * denom) {
            return ii{id, isrow} < ii{o.id, o.isrow};
        }
        return num * o.denom > o.num * denom;
    }
};
set<node> st;
set<ii> rst, cst;
int main() {
#ifndef DEBUG
    ios::sync_with_stdio(0), cin.tie(0);
#endif
    cin >> h >> w;
    REP (i, 0, h) {
        cin >> a[i];
    }
    REP (i, 0, w) {
        cin >> b[i];
    }
    REP (i, 0, h) {
        rst.insert({i, a[i]});
    }
    REP (i, 0, w) {
        cst.insert({i, b[i]});
    }
    REP (i, 1, h) {
        st.insert({a[i] - a[i - 1], 1, i, 1});
    }
    REP (i, 1, w) {
        st.insert({b[i] - b[i - 1], 1, i, 0});
    }
    while (h > 1 && w > 1) {
        auto [num, denom, id, isrow] = *st.begin(); st.erase(st.begin());
        cerr << num << ' ' << denom << ' ' << id << ' ' << isrow << '\n';
        cerr << h << ' ' << w << '\n';
        if (isrow) {
            auto ptr = rst.erase(rst.find({id, a[id]}));
            if (id == h - 1) {
                assert(ptr == rst.end());
                int nh = prev(rst.end()) -> FI + 1;
                ans += (ll) b[w - 1] * (h - nh);
                h = nh;
            } else {
                assert(ptr != rst.end() && ptr != rst.begin());
                st.erase({ptr -> SE - a[id],
                        ptr -> FI - id,
                        ptr -> FI, 1});
                st.insert({ptr -> SE - prev(ptr) -> SE,
                        ptr -> FI - prev(ptr) -> FI,
                        ptr -> FI, 1});
            }
        } else {
            auto ptr = cst.erase(cst.find({id, b[id]}));
            if (id == w - 1) {
                assert(ptr == cst.end());
                int nw = prev(cst.end()) -> FI + 1;
                ans += (ll) a[h - 1] * (w - nw);
                w = nw;
            } else {
                assert(ptr != cst.end() && ptr != cst.begin());
                st.erase({ptr -> SE - b[id],
                        ptr -> FI - id,
                        ptr -> FI, 0});
                st.insert({ptr -> SE - prev(ptr) -> SE,
                        ptr -> FI - prev(ptr) -> FI,
                        ptr -> FI, 0});
            }
        }
    }
    while (h > 1) {
        ans += b[0];
        h--;
    }
    while (w > 1) {
        ans += a[0];
        w--;
    }
    cout << ans << '\n';
    return 0;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |