Editorial for Đổi ngọc


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

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;
}

Comments

Please read the guidelines before commenting.


There are no comments at the moment.