1 条题解

  • 0
    @ 2025-8-24 22:07:42

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Caro23333
    Dream Theater 脑残粉

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

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

    以下是正文


    思路与Great_Influence相似,更加详细且有代码。

    首先观察题目条件。若tt是最小不整除xx的正整数,则有:

    • 对于任意i(1i<t)i(1\le i<t)都有ixi\mid x,即lcm(1,2,,t1)xlcm(1,2,\dots,t-1)\mid x
    • lcm(1,2,,t)xlcm(1,2,\dots,t)\nmid x

    根据这个原理我们进行打表不难发现使得lcm(1,2,,t)1018lcm(1,2,\dots,t)\le 10^{18}的最大的tt4242,从而对于3x10183\le x\le 10^{18}xx2t422\le t\le 42.

    114242每一个位置的前缀lcmlcm求出,并且考虑以i(2i42)i(2\le i\le 42)为转移点的x(43xn)x(43\le x\le n)的数量。注意到lcm(1,2,,i1)lcm(1,2,,i)lcm(1,2,\dots,i-1)\mid lcm(1,2,\dots,i),所以满足上述两个条件的xx的数量就是[43,n][43,n]lcm(1,2,,i1)lcm(1,2,\dots,i-1)的倍数的数量减去lcm(1,2,,i)lcm(1,2,\dots,i)的倍数的数量。

    注意到这些xx都满足f[x]=f[i]+1f[x] = f[i]+1,在预处理f[2],f[3],,f[42]f[2],f[3],\dots,f[42]之后可以计算出对于每个k(1k5)k(1\le k\le 5)共有几个xx满足f[x]=kf[x] = k,从而可以轻易地得到答案。

    时间复杂度显然是正确的。

    代码:

    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #define mod 1000000007
    
    using namespace std;
    typedef long long ll;
    const int MAXN = 50;
    int f[MAXN];
    ll n,lcm[MAXN],cnt[10];
    inline ll gcd(ll a, ll b)
    {
        return b?gcd(b,a%b):a;
    }
    inline ll calc(ll l, ll r, ll x)
    {
        return r/x-(l-1)/x; 
    }
    inline ll qpow(ll a, ll b)
    {
        ll res = 1;
        for(; b; a = a*a%mod, b >>= 1ll)
            if(b&1ll)
                res = res*a%mod;
        return res;
    }
    
    int main()
    {
        cin >> n;
        f[2] = 1;
        for(int i = 3; i<=50; i++)
            for(int j = 2; j<i; j++)
                if(i%j)
                {
                    f[i] = f[j]+1;
                    break;
                }
        lcm[1] = 1;
        int pos = 2;
        for(pos = 2; pos<=50; pos++)
      	{
            lcm[pos] = lcm[pos-1]*(pos/gcd(pos,lcm[pos-1]));
            if(lcm[pos]>n)
                break;
        }
        for(int i = 2; i<=pos; i++)
            cnt[f[i]+1] += calc(pos+1,n,lcm[i-1])-calc(pos+1,n,lcm[i]);
        for(int i = 2; i<=pos; i++)
            cnt[f[i]]++;
        ll ans = 1;
        for(int i = 2; i<=5; i++)
            ans = ans*qpow(i,cnt[i])%mod;
        cout << ans << endl;
        return 0;
    } 
    
    • 1

    信息

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