【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=\frac{(n!)^{2}}{k}+n! $。

  我们可以发现,$ x,y,n! $都是正整数,因此由$ y=n!+k $且$ y>n $可得$ k $也是正整数,而由$ x=\frac{(n!)^{2}}{k}+n! $可得$ \frac{(n!)^{2}}{k} $是正整数,所以k必为$ (n!)^2 $一因数。并且$ x,y $和$ k $的值是一一对应的,所以问题就变成了求$ (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

 

posted @ 2018-05-26 15:29  QuartZ_Z  阅读(255)  评论(0编辑  收藏  举报