CF1995C 题解

If we simulate the process, the numbers are too large even for long double.

But, we found that \(\log(x^2) = 2 \log(x)\). Therefore, we can make \(a_i \larr \log(a_i)\). Unfortunately, we might do this thousands of times, and \(2^{1000}\) is still too large.

But once again, we found that \(\log(2x) = \log(2) + \log(x)\). Because \(\log(2)\) is a small number, we can make \(a_i \larr \log(\log(a_i))\), then do the \(+\log(2)\) operation.

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <vector>

using namespace std;
using i64 = long long;

constexpr double EPS = 1e-9;

struct Solution {
    void solve()
    {
        int n;
        vector<int> arr;

        cin >> n;

        for (int i = 0; i < n; ++i) {
            int x;
            cin >> x;
            arr.emplace_back(x);
        }

        int l = 0;

        while (l < n && arr[l] == 1)
            ++l;

        vector<long double> lnln(n);

        for (int i = l; i < n; ++i) {
            if (arr[i] == 1) {
                cout << "-1\n";
                return;
            }

            lnln[i] = log((long double)log(arr[i]));
        }

        if (l > 0)
            lnln[l - 1] = log((long double)log(arr[l - 1]));

        i64 ans = 0;

        for (int i = max(l, 1); i < n; ++i) {
            long double need = lnln[i - 1] - lnln[i];

            if (need > EPS) {
                int cnt = 1 + (need - EPS) / log(2.0L);
                ans += cnt;
                lnln[i] += cnt * log(2.0L);
            }
        }

        cout << ans << '\n';
    }
};

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

    int t;
    cin >> t;

    while (t-- > 0)
        Solution().solve();

    return 0;
}
posted @ 2025-08-02 16:17  David9006  阅读(4)  评论(0)    收藏  举报