제출 #1359178

#제출 시각아이디문제언어결과실행 시간메모리
1359178eweirdf274rPilot (NOI19_pilot)C++20
100 / 100
301 ms42884 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

struct DSU {
    int n;
    vector<int> parent, sz;
    vector<bool> active;
    ll ans;

    DSU(int n) : n(n), parent(n+1), sz(n+1,1), active(n+1,false), ans(0) {
        for (int i = 1; i <= n; i++) parent[i] = i;
    }

    int find(int x) {
        if (parent[x] == x) return x;
        return parent[x] = find(parent[x]);
    }

    ll calc(ll s) {
        return s * (s + 1) / 2;
    }

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

        // union by size (optional but good)
        if (sz[a] < sz[b]) swap(a, b);

        // remove old contributions
        ans -= calc(sz[a]);
        ans -= calc(sz[b]);

        // merge
        parent[b] = a;
        sz[a] += sz[b];

        // add new contribution
        ans += calc(sz[a]);
    }

    void activate(int i) {
        active[i] = true;

        // new component of size 1
        parent[i] = i;
        sz[i] = 1;
        ans += 1; // calc(1)

        if (i > 1 && active[i - 1])
            unite(i, i - 1);

        if (i < n && active[i + 1])
            unite(i, i + 1);
    }
};

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

    int N, Q;
    cin >> N >> Q;

    vector<int> H(N+1);
    for (int i = 1; i <= N; i++) cin >> H[i];

    // sort indices by height
    vector<pair<int,int>> ord;
    for (int i = 1; i <= N; i++)
        ord.push_back({H[i], i});
    sort(ord.begin(), ord.end());

    // read queries
    vector<pair<int,int>> queries(Q);
    for (int i = 0; i < Q; i++) {
        cin >> queries[i].first;
        queries[i].second = i;
    }
    sort(queries.begin(), queries.end());

    DSU dsu(N);
    vector<ll> res(Q);

    int ptr = 0;

    for (auto [Y, idx] : queries) {
        // activate all heights ≤ Y
        while (ptr < N && ord[ptr].first <= Y) {
            dsu.activate(ord[ptr].second);
            ptr++;
        }
        res[idx] = dsu.ans;
    }

    // output
    for (int i = 0; i < Q; i++)
        cout << res[i] << '\n';

    return 0;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...