제출 #1331129

#제출 시각아이디문제언어결과실행 시간메모리
1331129_callmelucianSightseeing in Kyoto (JOI22_kyoto)C++20
100 / 100
303 ms15308 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;
using pl = pair<ll,ll>;
using pii = pair<int,int>;
using tpl = tuple<int,int,int>;

#define all(a) a.begin(), a.end()
#define filter(a) a.erase(unique(all(a)), a.end())

struct Fraction {
    ll a, b;

    Fraction() : a(0), b(1) {}
    Fraction (ll a, ll b) : a(a), b(b) {
        ll g = __gcd(abs(a), abs(b));
        a /= g, b /= g;
    }

    bool operator< (const Fraction &o) const {
        return a * o.b < o.a * b; // assume that both b and o.b > 0
    }

    bool operator== (const Fraction &o) const {
        return a * o.b == o.a * b;
    }

    bool operator!= (const Fraction &o) const {
        return a * o.b != o.a * b;
    }

    friend ostream& operator<< (ostream &oup, const Fraction &f) {
        return oup << 1.0 * f.a / f.b, oup;
    }
};

const int mn = 2e5 + 5;
int a[mn], b[mn];
multiset<int> sA, sB;

Fraction getFraction (int i, bool isA) {
    int prv = *prev((isA ? sA : sB).lower_bound(i));
    return isA ? Fraction(a[i] - a[prv], i - prv) : Fraction(b[i] - b[prv], i - prv);
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n, m; cin >> n >> m;
    priority_queue<tuple<Fraction,int,int>> pq;

    for (int i = 1; i <= n; i++) {
        cin >> a[i], sA.insert(i);
        if (i > 1) pq.emplace(Fraction(a[i] - a[i - 1], 1), i, 1);
    }
    for (int i = 1; i <= m; i++) {
        cin >> b[i], sB.insert(i);
        if (i > 1) pq.emplace(Fraction(b[i] - b[i - 1], 1), i, 0);
    }

    ll ans = 0, curX = n, curY = m;
    while (pq.size()) {
        Fraction u; int idx, isA; tie(u, idx, isA) = pq.top(); pq.pop();
        multiset<int> &curSet = (isA ? sA : sB);
        if (!curSet.count(idx) || getFraction(idx, isA) != u) continue;
        curSet.erase(idx);
        auto it = curSet.upper_bound(idx);
        if (it != curSet.end()) pq.emplace(getFraction(*it, isA), *it, isA);

        while (curX > *sA.rbegin()) curX--, ans += b[curY];
        while (curY > *sB.rbegin()) curY--, ans += a[curX];
    }
    cout << ans << "\n";

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...