北方大学 ACM 多校训练赛 第四场-D-积性函数(暴力,因子个数上界)

题目链接:北方大学 ACM 多校训练赛 第四场-D-积性函数

题意:定义函数f(n,0)=1;f(n,m)=sigma(d|n) f(d,m-1)*f(n/d,m-1)(m>0);求f(n,m)。
n<=1e9,m<=50。

根据暴力测试程序估算一下1~n中每个数因子个数的上界 f(n)
f(100)=6
f(1000)=16
f(10000)=32
f(100000)=64
f(1000000)=120
f(10000000)=224
推测出一个公式:
f(n)=2log10n+1

109 带进去答案是2048 。所以最多有2000个因子,所以暴力搞一搞。
先离散化一下,然后设 f(i,j) 为第i个因子,m=j时的值。然后dp算出来就行。。

设k为最大因子个数,时间复杂度为 O(mk2logk)

#include
using namespace std;
int f[3000][60];
const int mod=1e4+7;
vector<int> d;
int main()
{
    int T,n,m;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        d.clear();
        for(int i=1;i*i<=n;i++)
        {
            if(n%i==0)
            {
                d.push_back(i);
                if(i*i!=n) d.push_back(n/i);
            }
        }
        sort(d.begin(),d.end());
        n=d.size();
        for(int i=0;i0]=1;
        for(int j=1;j<=m;j++)
            for(int i=0;i0;
                for(int l=0;l<=i;l++)
                {
                    if(d[i]%d[l]) continue;
                    int r=lower_bound(d.begin(),d.end(),d[i]/d[l])-d.begin();
                    f[i][j]=(f[i][j]+f[l][j-1]*f[r][j-1])%mod;
                }
            }
        printf("%d\n",f[n-1][m]);
    }
    return 0;
}

你可能感兴趣的:(数论,暴力)