1 条题解

  • 0
    @ 2025-8-24 21:53:29

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar vegetabird
    **

    搬运于2025-08-24 21:53:29,当前版本为作者最后更新于2017-08-10 17:06:59,作者可能在搬运后再次修改,您可在原文处查看最新版

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

    以下是正文


    对于每一个N,我们先求出它的第ii小因子facifac_{i}, 然后记录下因子jj所对应的位置posjpos_{j}。这里有一个小技巧:

    ##+ifif jNj \le \sqrt{N}, 则令pos1j=posjpos1_{j}=pos_{j}

    ##+ifif j>Nj > \sqrt{N}, 则令pos2Nj=posjpos2_{\frac{N}{j}}=pos_{j}

    这样就可以把空间压缩为O(N)O(\sqrt{N})

    然后令dpijdp_{ij}为把facifac_{i}分解成若干个小于等于facjfac_{j}的数(包括11)的积的方案总数,则:

    #dpij=dpij1dp_{ij}=dp_{i j-1}

    #ifif i=ji=j, dpij++dp_{ij}++

    #ifif faci0,mod(facj)fac_{i} \equiv 0,mod( fac_{j}), dpij+=dpposfacifacjj1dp_{ij}+=dp_{pos_{\frac{fac{i}}{fac_{j}}} j-1}

    CODE:

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<utility>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<set>
    #include<iostream>
    #include<map>
    using namespace std;
    long long T,n;
    long long fac[11000];
    int dp[11000][11000];
    const long long mod=998244353;
    int pos1[1000010],pos2[1000010];
    map<long long,int>ans;
    int main(){
        cin>>T;
        register int i,j,s;long long q;
        while(T--){
            cin>>n;
            if(ans[n]){
                cout<<ans[n]<<endl;
                continue;
            }
            s=0;
            q=sqrt(n);
            if(n%q==0){
                fac[++s]=q;
                if(q*q!=n){
                    fac[++s]=n/q;
                }
            }
            for(i=1;i<q;i++){
                if(n%i==0){
                    fac[++s]=i;
                    fac[++s]=n/i;
                }
            }
            stable_sort(fac+1,fac+s+1);
            for(i=0;i<=s;i++){
                for(j=0;j<=s;j++){
                    dp[i][j]=0;
                }
            }
            for(i=1;i<=s;i++){
                dp[i][i]=1;
                if(fac[i]<=q){
                    pos1[fac[i]]=i;
                }else{
                    pos2[n/fac[i]]=i;
                }
            }
            for(i=1;i<=s;i++){
                for(j=1;j<=s;j++){
                    dp[i][j]+=dp[i][j-1];
                    if(i<=j){
                        continue;
                    }
                    if(fac[i]%fac[j]==0){
                        long long tmp=fac[i]/fac[j];
                        if(tmp<=q){
                            dp[i][j]+=dp[pos1[tmp]][j-1];
                        }else{
                            dp[i][j]+=dp[pos2[n/tmp]][j-1];
                        }
                        dp[i][j]%=mod;
                    }
                }
            }
            cout<<dp[s][s]-1<<endl;
            ans[n]=dp[s][s]-1;
        }
    }
    
    • 1

    信息

    ID
    2817
    时间
    3000ms
    内存
    500MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者