1 条题解

  • 0
    @ 2026-5-7 21:56:16

    题目链接

    P6276 [USACO20OPEN] Exercise P

    题意简述

    求所有长度为 nn 的排列的所有置换环长度的 lcm\operatorname*{lcm} 的乘积。

    1n75001 \le n \le 7500

    解题思路 & 参考代码

    根据 min,max\min,\max 容斥有 gcd,lcm\gcd,\operatorname*{lcm} 容斥:$\operatorname*{lcm}_{x \in S} x = \prod_{T \subseteq S}(\gcd_{x \in T} x)^{(-1)^{|T| - 1}}$。

    于是原问题被转化为了对子集的 gcd\gcd 计数,注意要带上容斥系数。

    考虑钦定 gcd\gcdxx 来计算答案。

    为了方便计算,考虑先预处理出 fif_i 表示 ii 个位置分成若干个置换环的方案数,考虑钦定新增的环在首位,有转移:

    $$f_{i+j} \gets f_i \times \binom{i+j-1}{j-1} \times (j-1)!$$

    然后进行 dp,gig_i 表示凑出 ixix 的方案数(带容斥系数):

    $$g_{j+k} \gets (-1) \times g_j \binom{(j+k)\times x-1}{k \times x-1} \times (k \times x - 1)!$$

    那么钦定 gcd=x\gcd = x 的答案 $ans_x = \displaystyle\sum_{i=1}^{\lfloor\frac{n}{x}\rfloor} g_i f_{n-ix}\binom{n}{ix}$。

    对着 ansans 容斥一下即可还原出 gcd\gcd 严格为 xx 的答案。

    最终答案即为 i=1niansi\prod_{i=1}^{n} i^{ans_i}

    时间复杂度 O(n2)O(n^2)

    因为 ansians_i 是指数上的,所以前面都要要 mod (p1)\bmod \ (p - 1),模数不是质数,所以要 n2n^2 预处理一下组合数。

    :::info[参考代码]

    int n;
    int f[7510],g[7510],ans[7510];
    int C[7510][7510],A[7510][7510];
    int fac[7510];
    void solve()
    {
        cin>>n>>mod;
        mod--;
        fac[0]=1;
        forl(i,1,7505)
            fac[i]=1ll*fac[i-1]*i%mod;
        C[0][0]=1;
        forl(i,1,7505)
        {
            A[i][0]=C[i][0]=1;
            forl(j,1,i)
                C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod,
                A[i][j]=1ll*C[i][j]*fac[j]%mod;
        }
        f[0]=1;
        forl(i,0,7500)
            forl(j,1,7500-i)
            {
                if(i!=0)
                    add(f[i+j],1ll*f[i]*A[i+j-1][j-1]%mod);
                else
                    add(f[i+j],1ll*f[i]*fac[j-1]%mod);
            }
        forl(i,1,n)
        {
            ll lim=n/i;
            forl(j,0,lim+5)
                g[j]=0;
            g[0]=mod-1;
            forl(j,0,lim)
                forl(k,1,lim-j)
                {
                    if(j!=0)
                        add(g[j+k],mod-1ll*g[j]*A[(j+k)*i-1][k*i-1]%mod);
                    else
                        add(g[j+k],mod-1ll*g[j]*fac[k*i-1]%mod);
                }
            forl(j,1,lim)
                add(ans[i],1ll*g[j]*f[n-i*j]%mod*C[n][i*j]%mod);
        }
        forr(i,n,1)
            forll(j,i*2,n,i)
                add(ans[i],mod-ans[j]);
        mod++;
        long long S=1;
        forl(i,1,n)
            S=S*pw(i,ans[i],mod)%mod;
        cout<<S<<endl;
    }
    

    :::

    • 1

    信息

    ID
    7085
    时间
    1000ms
    内存
    512MiB
    难度
    8
    标签
    递交数
    21
    已通过
    6
    上传者