QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#613656#9435. Welcome to NPCAPCucup-team3646#WA 0ms3836kbC++204.7kb2024-10-05 14:25:542024-10-05 14:25:55

Judging History

你现在查看的是最新测评结果

  • [2024-10-05 14:25:55]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3836kb
  • [2024-10-05 14:25:54]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

template <typename T>
class LeftistHeap {
public:
    LeftistHeap() = default;

    static LeftistHeap meld(LeftistHeap a, LeftistHeap b) {
        return LeftistHeap(meld(std::move(a.root), std::move(b.root)));
    }

    std::pair<int, T> top() const {
        push(root);
        return {root->id, root->val};
    }

    void pop() {
        push(root);
        root = meld(std::move(root->left), std::move(root->right));
    }

    void push(int id, T x) {
        root = meld(std::move(root), std::make_unique<Node>(id, x));
    }

    bool empty() const { return root == nullptr; }

    void add(T x) { root->lazy += x; }

private:
    struct Node;
    using node_ptr = std::unique_ptr<Node>;

    struct Node {
        node_ptr left, right;
        int s;
        int id;
        T val, lazy;
        Node(int id, T x) : id(id), val(x), lazy(0) {}
    };

    node_ptr root = nullptr;

    explicit LeftistHeap(node_ptr root) : root(std::move(root)) {}

    static node_ptr meld(node_ptr a, node_ptr b) {
        if (!a) return b;
        if (!b) return a;
        push(a);
        push(b);
        if (a->val > b->val) std::swap(a, b);
        a->right = meld(std::move(a->right), std::move(b));
        if (!a->left || a->left->s < a->right->s) std::swap(a->left, a->right);
        a->s = (a->right ? a->right->s : 0) + 1;
        return a;
    }

    static void push(const node_ptr& t) {
        if (t->left) t->left->lazy += t->lazy;
        if (t->right) t->right->lazy += t->lazy;
        t->val += t->lazy;
        t->lazy = 0;
    }
};

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int) v.size(); ++i) {
        os << v[i];
        if (i < (int) v.size() - 1) os << " ";
    }
    return os;
}

template <typename T>
T hu_tucker(std::vector<T> vs) {
    const int n = vs.size();
    const ll INF = std::numeric_limits<T>::max() / 2;
    std::vector<LeftistHeap<T>> heaps(n - 1);  // interior nodes in each group
    std::vector<int> left(n), right(n);
    std::vector<T> cs(n - 1);
    using P = std::pair<T, int>;
    std::priority_queue<P> pq;
    for (int i = 0; i < n - 1; ++i) {
        left[i] = i - 1;
        right[i] = i + 1;
        cs[i] = vs[i] + vs[i + 1];
        pq.emplace(cs[i], i);
    }
    T ret = 0;
    for (int k = 0; k < n - 1; ++k) {
        T c;
        int i;
        // find the optimal nodes to merge
        do {
            tie(c, i) = pq.top();
            pq.pop();
        } while (right[i] == -1 || cs[i] != c);

        bool merge_l = false, merge_r = false;
        if (vs[i] + vs[right[i]] == c) {  // lr
            merge_l = merge_r = true;
        } else {
            T top = heaps[i].top().second;
            heaps[i].pop();
            if (vs[i] + top == c) {  // lm
                merge_l = true;
            } else if (top + vs[right[i]] == c) {  // mr
                merge_r = true;
            } else {  // mm
                heaps[i].pop();
            }
        }
        ret += c;
        heaps[i].push(-1, c);
        if (merge_l) {
            vs[i] = -INF;
        }
        if (merge_r) {
            vs[right[i]] = -INF;
        }

        // merge left
        if (merge_l && i > 0) {
            int j = left[i];
            heaps[j] = LeftistHeap<T>::meld(std::move(heaps[j]), std::move(heaps[i]));
            right[j] = right[i];
            right[i] = -1;
            left[right[j]] = j;
            i = j;
        }
        // merge right
        if (merge_r && right[i] < n - 1) {
            int j = right[i];
            heaps[i] = LeftistHeap<T>::meld(std::move(heaps[i]), std::move(heaps[j]));
            right[i] = right[j];
            right[j] = -1;
            left[right[i]] = i;
        }

        cs[i] = vs[i] + vs[right[i]];  // lr
        if (!heaps[i].empty()) {
            T top = heaps[i].top().second;
            heaps[i].pop();
            cs[i] = std::max(cs[i], std::max(vs[i], vs[right[i]]) + top);  // lm or mr
            if (!heaps[i].empty()) {
                cs[i] = std::max(cs[i], top + heaps[i].top().second);  // mm
            }
            heaps[i].push(-1, top);
        }
        pq.emplace(cs[i], i);
    }
    return ret;
}

int main() {
  ll N, M; cin >> N >> M;
  vector<ll> A(N);
  for (auto &a : A) cin >> a;
  A.emplace_back(0);
  A.emplace_back(M+1);

  sort(A.begin(), A.end());
  
  vector<ll> B;
  for (int i = 1; i < A.size(); ++i) {
    B.emplace_back((A[i] - A[i-1]));
  }

  ll res = hu_tucker(B);
  cout << res << endl;

  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 3836kb

input:

4
12
6
5839
123456

output:

493805

result:

wrong answer 1st numbers differ - expected: '924', found: '493805'