Hướng dẫn giải của Đổi ngọc


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Ta đánh số lại cấp độ ngọc từ ~0~ đến ~n-1~. Nhận xét rằng, ngọc cấp ~i~ có thể quy đổi thành ~2^i~ ngọc cấp ~1~ (và ngược lại, ~2^i~ ngọc cấp ~1~ có thể đổi thành một ngọc cấp ~i~). Do đó, một ngọc cấp ~i~ sẽ có giá trị tương đương ~2^i~ ngọc cấp ~1~. Với nhận xét trên, ta có thể tính tổng giá trị ngọc đang có, và so sánh nó với tổng giá trị ngọc cần có.

Tuy nhiên, với giới hạn ~n \le 2 \times 10^5~ thì tổng giá trị ngọc là quá lớn để biểu diễn bằng số nguyên 64 bit. Để cải tiến, ta biểu diễn tổng giá trị ngọc bằng một dãy nhị phân (duyệt các cấp độ ngọc từ nhỏ đến lớn, rồi thực hiện giống phép cộng số nguyên lớn trong hệ nhị phân), rồi thực hiện so sánh hai dãy nhị phân như việc so sánh hai số nguyên lớn. Độ phức tạp là ~O(n + \log X)~ với ~X~ là giới hạn số lượng ngọc ban đầu ở từng cấp độ.

#include <bits/stdc++.h>

using namespace std;

void solve() {
    int n; cin >> n;
    int k = n + 100;
    vector<int> a(k), b(k);
    for(int i = 0; i < n; ++i) cin >> a[i];
    for(int i = 0; i < n; ++i) cin >> b[i];

    for(int i = 0; i < k-1; ++i) {
        a[i+1] += a[i]/2;
        a[i] %= 2;
    }
    for(int i = 0; i < k-1; ++i) {
        b[i+1] += b[i]/2;
        b[i] %= 2;
    }

    for(int i = k-1; i >= 0; --i) {
        if (a[i] > b[i]) {
            puts("YES");
            return;
        } else if (a[i] < b[i]) {
            puts("NO");
            return;
        }
    }

    puts("YES");
    return;
}

int main() {
    int t; cin >> t;
    while (t--) solve();

    return 0;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.