【题解】CF1997E Level Up

难度:\(3/10\)

\(O(n\log^3n)\) 的做法的调和级数 + 二分 + 内层 ds 做法是简单的,但是因为 \(n\) 很大所以难以通过。

考虑优化。注意到若 \(k\) 确定为一个值的时候,某个怪物不会逃跑,那么 \(k\) 增大的时候这个怪物一定不会逃跑。同理,若 \(k\) 为一个值的时候某个怪物会逃跑,那么 \(k\) 减小的时候这个怪物一定也会逃跑。因此考虑让 \(k\) 从小到大扫描,然后每次增大处理出二分处理出新的不会逃跑的怪物,用树状数组简单维护即可做到 \(O(nlog^2n)\)

namespace Loyalty
{
    int a[N];
    struct BIT
    {
        int tree[N];
        inline BIT() { memset(tree, 0, sizeof tree); }
        inline void clr(int x) { for (; x < N; x += (x &- x)) tree[x] = 0; }
        inline void add(int x, int v) { for (; x < N; x += (x &- x)) tree[x] += v; }
        inline int qry(int x) { int s = 0; for (; x; x -= (x &- x)) s += tree[x]; return s; }
        inline int qry(int l, int r) { return qry(r) - qry(l - 1); }
    } fwt;
    int to[N];
    inline void init() {}
    inline void main([[maybe_unused]] int _ca, [[maybe_unused]] int _atc)
    {
        int n, q;
        cin >> n >> q;
        for_each(a + 1, a + n + 1, [&](auto &input) { cin >> input; });
        for (int i = 1; i <= n; ++i)
        {
            int l = 1, r = n, best = 0;
            while (l <= r)
            {
                int mid = l + r >> 1;
                (mid * a[i] <= fwt.qry(mid)) ? (best = mid, l = mid + 1) : (r = mid - 1);
            } ++best;
            fwt.add(to[i] = best, 1);
        }
        while (q--)
        {
            int i, x;
            cin >> i >> x;
            cout << ((x >= to[i]) ? "Yes" : "No") << '\n';
        }
    }
}
posted @ 2026-02-03 17:09  0103abc  阅读(4)  评论(0)    收藏  举报