제출 #995201

#제출 시각아이디문제언어결과실행 시간메모리
995201LOLOLO등산 경로 (IZhO12_route)C++14
100 / 100
94 ms30548 KiB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
 
#define           f     first
#define           s     second
#define           pb    push_back
#define           ep    emplace
#define           eb    emplace_back
#define           lb    lower_bound
#define           ub    upper_bound
#define       all(x)    x.begin(), x.end()
#define      rall(x)    x.rbegin(), x.rend()
#define   uniquev(v)    sort(all(v)), (v).resize(unique(all(v)) - (v).begin())
#define     mem(f,x)    memset(f , x , sizeof(f))
#define        sz(x)    (ll)(x).size()
#define  __lcm(a, b)    (1ll * ((a) / __gcd((a), (b))) * (b))
#define          mxx    *max_element
#define          mnn    *min_element
#define    cntbit(x)    __builtin_popcountll(x)
#define       len(x)    (int)(x.length())

const int N = 1e6 + 10;
int p[N], sz[N], l[N], r[N], a[N * 2];

int get(int x) {
    return p[x] ? get(p[x]) : x;
}

void unite(int a, int b) {
    a = get(a), b = get(b);
    if (a == b)
        return;

    if (sz[a] < sz[b])
        swap(a, b);

    p[b] = a;
    sz[a] += sz[b]; 
    l[a] = min(l[a], l[b]);
    r[a] = max(r[a], r[b]);
} 

int solve() {
    int n, k;
    cin >> n >> k;

    int p = 1;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        if (a[i] > a[p])
            p = i;

        sz[i] = 1;
        l[i] = r[i] = i;
    }

    for (int i = 1; i < p; i++) {
        a[n + i] = a[i];
    }

    for (int i = 1; i <= n; i++) {
        a[i] = a[i + p - 1];
    }

    a[n + 1] = a[1];

    for (int i = 1; i < n; i++) {
        if (a[i] == a[i + 1]) {
            unite(i, i + 1);
        }
    }

    priority_queue <pair <int, int>, vector <pair <int, int>>, greater <pair <int, int>>> pq;

    for (int i = 1; i <= n; i++) {
        int t = get(i);
        int x = l[t] - 1, y = r[t] + 1;
        if (min(a[x], a[y]) > a[t]) {
            pq.push({r[t] - l[t] + 1, t});
        }

        i = r[t];
    }

    ll ans = 0;
    while (sz(pq) && k) {
        auto t = pq.top();
        pq.pop();
        if (t.f > k)
            break;

        int root = get(t.s);
        int x = get(l[root] - 1), y = get(r[root] + 1);
        int diff = min(a[x], a[y]) - a[root];
        int cc = min(k / t.f, diff);

        k -= cc * t.f;
        ans += cc * 2;
        a[root] += cc;

        if (a[root] == a[x]) {
            unite(root, x);
        }

        if (a[root] == a[y] && y <= n) {
            unite(root, y);
        }

        root = get(root);
        x = get(l[root] - 1), y = get(r[root] + 1);
        if (a[root] < min(a[x], a[y])) {
            pq.push({r[root] - l[root] + 1, root});
        }
    }

    return ans;
}

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

    int t = 1;
    //cin >> t;

    while (t--) {
        cout << solve() << '\n';
    }

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