1 条题解

  • 0
    @ 2026-5-6 20:51:47

    怎么还没有人写题解。

    讲一下我的方法。
    预处理过程:对于每一个 aia_i,标记一下,接下来做一个前缀和 sumsumsumisum_i 表示小于 ii 的数有多少个。
    验证过程:对于每一个存在的数字 yy,检查所有可能的 kk 值,确保对于每个区间 [ky,(k+1)y1][k \cdot y, (k + 1) \cdot y - 1],如果该区间内存在数组中的元素,则 kk 也必须存在于数组中。
    时间复杂度 O(ClogC) O(C \log C) ,可以通过。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e7 + 1;
    bool vis[N];
    int T, n, c, a[N];
    bool check() 
    {
        for(int y = 1; y <= c; y++) 
        {
            if(!vis[y]) continue;  
            for(int k = 1; k * y <= c; k++) //枚举所有可能的k
            {
                if(a[min((k + 1) * y - 1, c)] - a[k * y - 1] > 0) //若改区间内存在数组中的元素
                {
                    if(!vis[k]) 
                    {
                        return 0; 
                    }
                }
            }
        }
        return 1;
    }
    int main() 
    {
        cin >> T;
        while(T--) 
        {
            cin >> n >> c;
            for(int i = 1; i <= c; i++)
            {
                vis[i] = 0;
            }//这里千万不要用memset!
            for(int i = 1; i <= n; i++)
            {
                int x;
                cin >> x;
                vis[x] = 1;//标记
            }
            for(int i = 1; i <= c; i++)
            {
                a[i] = a[i - 1] + vis[i];
            }//做前缀和
            if(check()) cout << "Yes\n";
            else cout << "No\n";
        }
        return 0;
    }
    
    • 1

    信息

    ID
    11062
    时间
    2000ms
    内存
    1024MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者