1 条题解

  • 0
    @ 2025-8-24 21:26:39

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 沉冥Charming
    我,爆零qaq

    搬运于2025-08-24 21:26:38,当前版本为作者最后更新于2019-08-26 22:23:54,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题目中的超级数跟反素数的定义是一样的

    反素数就是尽可能地让因子数量最大,但是数值最小。

    性质一:一个反素数的质因子必然是从2开始连续的质数.

    性质二:p= (2^t1)(3^t2)(5^t3)(7^t4)..... 必然t1>=t2>=t3>=....

    但是似乎没有人发生成反素数表的代码呢……

    蒟蒻决定凑个热闹发一个生成反素数表的代码

    根据数据范围,我们很容易想到暴力+打表

    根据反素数的两条性质枚举,求出含有i个因数的最小正整数

    所以我们先要打出一张质数表 代码如下:

    #include<iostream>
    #include<fstream>
    using namespace std;
    bool isprime(int x)
    {
        if (x<2)
            return false;
        for (int i=2; i*i<=x; i++)
            if (x%i==0)
                return false;
        return true;
    }
    int main()
    {
        freopen("prime.txt","w",stdout);
        int a=0;
        for (int i=1;i<=100;i++)
        {
            if (isprime(i))
            {
                cout<<i<<",";
                a++;
            }
            if (a==5)
            {
                cout<<endl;
                a=0;
            }
        }
        return 0;
    }
    /*
    1:2
    2:6
    3:30
    4:210
    5:2310
    6:30030
    7:510510
    8:9699690
    9:223092870
    10:6469693230
    11:200560490130
    12:7420738134810
    13:304250263527210
    14:13 08276 13316 70030
    */
    

    将这些质数乘起来,显而易见在题目数据范围内,只需要用到前13个质数

    于是我们用暴搜打出反素数表 代码如下:

    #include<iostream>
    #include<cstring>
    #include<fstream>
    #define ll long long
    #define mmax 0x3f3f3f3f3f3f3f3f
    using namespace std;
    ll p[26]=
    {
        0,
        2,3,5,7,11,
        13,17,19,23,29,
        31,37,41,43,47,
        53,59,61,67,71,
        73,79,83,89,97
    };
    ll ap[100001];
    void dfs (ll n,ll y,ll t,ll x)
    {
        if (n>=14)
            return;
        ll k=t;
        for (ll i=1; i<=x; i++)
        {
            k*=p[n];
            if (k>1e17)
                break;
            int ys=y*(i+1);
            if (k<ap[ys])
                ap[ys]=k;
            dfs(n+1,ys,k,i);
        }
    }
    int main()
    {
        freopen("antiprime.txt","w",stdout);
        int hh=0;
        memset(ap,0x3f,sizeof(ap));
        ap[0]=0,ap[1]=1;
        dfs(1,1,1,60);
        for (int i=0; i<=100000; i++)
            if(ap[i]!=mmax)
            {
                int flag=0;
                for (int j=i; j<=100000; j++)
                    if (ap[i]>ap[j])
                    {
                        flag=1;
                        break;
                    }
                if (!flag)
                {
                    hh++;
                    cout<<ap[i]<<",";
                }
                if (hh==5)
                {
                    cout<<endl;
                    hh=0;
                }
            }
        return 0;
    }
    

    打出反素数表之后就很容易ac了,但是要注意读入是用long long,不然就只有70分了

    十年 OI 一场空,不开 long long 见祖宗

    由于是打表,题目中的询问次数不超过十万次,而数据范围内的反素数并不多,所以连二分查找都不需要就能轻松ac

    ac代码就不附了,毕竟可以看其他大佬的题解QwQ

    • 1

    信息

    ID
    567
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者