P13546 [OOI 2022] Integral Array 题解

题意简析

若一个可重集合 \(a\) 满足其中任意两个元素 \(x,y\),且 \(x \ge y\)\(\left\lfloor \frac{x}{y} \right\rfloor \in a\),那么称 \(a\) 为整性数组。

现在给你若干个数组,试判断它们是否为整性数组。

思路解析

直接枚举所有数对 \(x\)\(y\) 的时间复杂度为 \(O(n^2)\),对于 \(n \le 10^6\) 不可行的。

注意到题目中给出了值域 \(1 \le c \le 10^7\),因此我们考虑从这方面下手,可以考虑到复杂度和值域相关的桶。

对于数组中出现的每个数 \(y\),以及每个可能的商 \(k\),如果存在一个数 \(x\) 在区间 \([ky, k(y+1) - 1]\) 内,那么 \(k\) 必须存在于数组中。否则,数组不是整性的。

但是我们如何查询呢?我们可以考虑使用前缀和:类似于欧拉筛的思想,对于每个在数组中出现的 \(y\),枚举所有可能的 \(k\)(从 \(1\)\(\left\lfloor \frac{c}{y} \right\rfloor\))。对于每个 \(k\),如果 \(k\) 不在数组中,查询区间 \([k y, \min(k(y+1) - 1, c)]\) 是否有元素存在。若存在,则数组不满足条件。

优化

  • 特判:如果数组包含从 \(1\)\(c\) 的所有整数,则直接判定为整性数组。
  • 特殊情况:注意到 \(x\) 可以等于 \(y\),那么 \(\frac{x}{x} = 1(x \ne0)\),因此若数组之中没有 \(1\) 肯定不是整性数组。

时间复杂度

调和级数求和:

\[H_n = \sum_{k=1}^n \frac{1}{k} \]

故时间复杂度为:

\[O(c \ln(c)) \]

代码实现

#pragma G++ optimize("O3", "unroll-loops", "omit-frame-pointer", "inline")
#include <bits/stdc++.h>
using namespace std;
const int MAX_C = 1e7 + 1;
bool has[MAX_C];
int n, c, t, pref[MAX_C];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> t;
    while (t--) {
        cin >> n >> c;
        for (int i = 1; i <= c; i++) {
            has[i] = false;
        }
        for (int i = 0, x; i < n; i++) {
            cin >> x;
            has[x] = true;
        }
        for (int i = 1; i <= c; i++) {
            pref[i] = pref[i - 1] + has[i];
        }
        if (pref[c] == c) {
            cout << "Yes\n";
            continue;
        }
        bool valid = true;
        for (int y = 1; y <= c && valid; y++) {
            if (has[y]) {
                for (int k = 1; k * y <= c; k++) {
                    if (!has[k]) {
                        if (pref[min(k * y + y - 1, c)] - pref[k * y - 1] > 0) {
                            valid = false;
                            break;
                        }
                    }
                }
            }
        }

        if (valid) {
            cout << "Yes\n";
        } else {
            cout << "No\n";
        }
    }
    return 0;
}

后记

双倍经验

posted @ 2025-08-02 19:41  TangyixiaoQAQ  阅读(15)  评论(0)    收藏  举报