题解:B3929 [GESP202312 五级] 小杨的幸运数

B3929 题解

题意

给定 \(N\) 个数 \(x_i (1 \le i \le N)\),判断 \(x_i\) 是否是大于等于 \(a\) 的完全平方数或者完全平方数的倍数。如果是,输出 lucky,否则输出最小的大于 \(x_i\) 的完全平方数或者完全平方数的倍数。

需要的算法

筛法、二分

题解

如果你直接暴力求解,无法 AC 本题全部数据。

考虑提前筛选所有的符合要求的数,存储下来,如果 \(x_i\) 符合要求,直接输出 lucky,否则二分查找最小的大于 \(x_i\) 的符合要求的数。

Code

#include <bits/stdc++.h>
using namespace std;
/*====================*/
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
/*====================*/
#define endl '\n'
/*====================*/
const int A=1002001;
const int N=A+10;
/*====================*/
class Lucky
{
private:
    bitset<N> is_lucky;
    vector<int> luck;
    bool Is_Square(int x)
    {
        int _x=sqrt(x);
        return _x*_x==x;
    }
    int Binary_Search(int x)
    {
        int res=-1;
        int l=0,r=luck.size()-1;
        while(l<=r)
        {
            int mid=l+r>>1;
            if(luck[mid]>x)res=luck[mid],r=mid-1;
            else l=mid+1;
        }
        return res;
    }
public:
    Lucky(void){}
    Lucky(int a)
    {
        for(int i=a;i<=A;i++)
        {
            if(Is_Square(i))
            {
                for(int j=i;j<=A;j+=i)
                {
                    is_lucky[j]=true;
                    luck.push_back(j);
                }
            }
        }
        sort(luck.begin(),luck.end());
    }
    void GetAnswer(int x)
    {
        if(is_lucky[x])cout<<"lucky"<<endl;
        else cout<<Binary_Search(x)<<endl;
    }
};
/*====================*/
void Solve(void)
{
    int a,n;cin>>a>>n;
    Lucky luck(a);
    while(n--)
    {
        int x;cin>>x;
        luck.GetAnswer(x);
    }
}
/*====================*/
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr),cout.tie(nullptr);
    int T=1;//cin>>T;
    while(T--) Solve();
    return 0;
}
posted @ 2025-09-07 10:27  yufh  阅读(98)  评论(0)    收藏  举报
浏览器标题切换
浏览器标题切换end