bzoj2721[Violet 5]樱花

Posted QuartZ_Z

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2721[Violet 5]樱花相关的知识,希望对你有一定的参考价值。

  题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=2721

  好久没做数学题了,感觉有些思想僵化,走火入魔了。

  这道题就是求方程$ \frac{1}{x}+\frac{1}{y}=\frac{1}{n!} $的正整数解个数。

  首先我们可以把方程化为$ (x+y)n!=xy $。。。然后就发现搞不出什么了。

  但是我们可以考虑换元,因为$ x,y $必大于$ n $,所以我们设$ y=n!+k $,然后我们就可以把方程化为$ (x+n!+k)n!=x(n!+k) $,接下来去括号并整理得:$ (n!)^{2}+kn!=xk $,于是$ x=x=\frac{(n!)^{2}}{k}+n! $,问题就变成了求$ (n!)^2 $的因数个数。

  具体做法可以用筛法筛出质数,然后对于每个质数,算出它们的每个幂对答案的贡献。

  代码:

技术分享图片
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#define ll long long
#define ull unsigned long long
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define lowbit(x) (x& -x)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define eps 1e-18
#define maxn 500010
inline ll read()
{
    ll tmp=0; char c=getchar(),f=1;
    for(;c<0||9<c;c=getchar())if(c==-)f=-1;
    for(;0<=c&&c<=9;c=getchar())tmp=(tmp<<3)+(tmp<<1)+c-0;
    return tmp*f;
}
int p[1000010],mn[1000010];
ll cnt[1000010];
int n,tot=0;
void eular(int n)
{
    mn[1]=1;
    for(int i=2;i<=n;i++){
        if(!mn[i])p[++tot]=i,mn[i]=tot;
        for(int j=1;j<=mn[i]&&i*p[j]<=n;j++)mn[i*p[j]]=p[j];
    }
    //for(int i=1;i<=n;i++)
    //    if(p[mn[i]]==i)printf("%d\n",i);
}
int main()
{
    n=read();
    eular(n);
    for(int i=1;i<=tot;i++){
        cnt[i]=0;
        for(ll j=p[i];j<=n;j*=p[i])cnt[i]+=n/j;
        cnt[i]%=mod;
    }
    ll ans=1;
    for(int i=1;i<=tot;i++)
        ans=ans*(cnt[i]*2+1)%mod;
    printf("%lld\n",ans);
    return 0;
}
bzoj2721

 

以上是关于bzoj2721[Violet 5]樱花的主要内容,如果未能解决你的问题,请参考以下文章

bzoj2721[Violet 5]樱花

bzoj2721: [Violet 5]樱花

bzoj2721 [Violet 5]樱花

bzoj2721[Violet 5]樱花 数论

Bzoj2721 [Violet]樱花(筛法)

2721: [Violet 5]樱花|约数个数