bzoj 2721

 题解:首先推一发式子(见csdn https://blog.csdn.net/lleozhang/article/details/83415995

因为x是整数,所以x的数量显然为能使取得整数的t的个数,也就是求的约数个数

而根据约数个数和公式(设一个数)

可以将前n个数质因子分解,然后将质因子的幂次相乘,最后将所有幂次*2+1后乘在一起即可。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define ll long long
#define mode 1000000007
#define maxn 1000000
using namespace std;
ll fac[1000005];
ll pri[1000005];
bool used[1000005];
int tot=0;
int n;
void init()
{
    scanf("%d",&n);
    for(int i=2;(ll)i*i<=n;i++)
    {
        if(!used[i])
        {
            pri[++tot]=i;
        }
        for(int j=1;j<=tot&&(ll)i*pri[j]<=n;j++)
        {
            used[i*pri[j]]=1;
            if(i%pri[j]==0)
            {
                break;
            }
        }
    }
    for(int i=2;i<=n;i++)
    {
        int t=i;
        for(int j=1;(ll)pri[j]*pri[j]<=t&&j<=tot;j++)
        {
            while(t%pri[j]==0)
            {
                fac[pri[j]]++;
                t/=pri[j];    
                if(fac[pri[j]]>=mode)
                {
                    fac[pri[j]]-=mode;
                }
            }
        }
        if(t!=1)
        {
            fac[t]++;
            if(fac[t]>=mode)
            {
                fac[t]-=mode;
            }        
        }
    }  
    ll ans=1;
    for(int i=1;i<=n;i++)
    {
        fac[i]<<=1;
        fac[i]%=mode;
        ans*=(fac[i]+1);
        ans%=mode;
    }
    printf("%lld\n",ans);
}
int main()
{
    init();
    return 0;
}

 

posted @ 2018-10-26 15:44  lleozhang  Views(189)  Comments(0Edit  收藏  举报
levels of contents