【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

原文地址:https://www.cnblogs.com/quzhizhou/p/9093040.html

时间: 2024-08-30 12:29:23

【bzoj2721】[Violet 5]樱花的相关文章

【筛法求素数】【质因数分解】bzoj2721 [Violet 5]樱花

http://www.cnblogs.com/rausen/p/4138233.html #include<cstdio> #include<iostream> using namespace std; #define MOD 1000000007 int n; bool Not[1000001]; int pr[1000001],e,ci[1000001]; void shai() { Not[1]=1; for(int i=2;i<=1000;++i) if(!Not[i

BZOJ2721 [Violet 5]樱花

先令n! = a: 1 / x + 1 / y = 1 / a  =>  x = y * a / (y - a) 再令 k = y - a: 于是x = a + a ^ 2 / k  =>  k | a ^ 2 故等价于求a ^2的约数个数 素数筛一下什么的就好了嘛 1 /************************************************************** 2 Problem: 2721 3 User: rausen 4 Language: C++ 5

【bzoj2721】[Violet 5]樱花 数论

题目描述 输入 输出 样例输入 2 样例输出 3 题解 数论 设1/x+1/y=1/m,那么xm+ym=xy,所以xy-xm-ym+m^2=m^2,所以(x-m)(y-m)=m^2. 所以解的数量就是m^2的约数个数. 所以只需要算出n!中每个素数的出现次数即可. 我们可以先快筛出1~n的素数,然后考虑每个素数出现的次数. 而p出现的次数为包含p^1的数的个数+包含p^2的数的个数+...+包含p^k的数的个数,我们可以迭代来求. 最后把它们乘2加1再乘到一起即可. #include <cstd

Bzoj2721 [Violet]樱花(筛法)

题面 题解 首先化一下式子 $$ \frac 1x+\frac 1y=\frac 1{n!} \Rightarrow \frac {x+y}{xy}=\frac 1{n!} \Rightarrow (x+y)n!=xy \\ \Rightarrow(n!-x)+(n!-y)=(n!)^2 $$ 看到最后一个式子,由于$n!$是唯一确定的,所以只要确定了$x$,$y$也是确定的,而且是唯一确定的一组$(x,y)$. 根据唯一分解定理,$n!=p_1^{k_1}p_2^{k_2}...p_m^{k_

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

先跪一发题目背景QAQ 显然x,y>n!,然后可以设y=n!+d 原式子可以化简成 x=n!2d+n! 那么解的个数也就是n!的因子个数,然后线性筛随便搞一搞 #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<queue> #include<vector> #include<set> #include<ma

BZOJ 2721 Violet 5 樱花 数论

题目大意:给定n,求有多少正整数数对(x,y)满足1x+1y=1n! 由于x,y>0,故显然有y>n! 不妨设y=n!+t(t>0),那么有 1x+1n!+t=1n! 化简后得到 n!(n!+t)+x(n!)=x(n!+t) x=(n!)2t+n! 故答案为d((n!)2) #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #defin

BZOJ_2721_[Violet 5]樱花_数学

Description Input Output $\frac{1}{x}+\frac{1}{y}=\frac{1}{m}$ $xm+ym=xy$ $(x-m)*(y-m)=m^{2}$ 于是转化为了求$n!$的约数个数 可以用每个质因子搞一下 代码: #include <stdio.h> #include <string.h> #include <algorithm> #include <stdlib.h> using namespace std; #de

P4167 [Violet]樱花

题目背景 又到了一年樱花盛开的时节.Vani 和妹子一起去看樱花的时候,找到了一棵大大的樱 花树,上面开满了粉红色的樱花.Vani 粗略估计了一下,一共有足足  n! 片花瓣. Vani 轻柔地对她说:“你知道吗?这里面的一片花瓣代表着你,我从里面随机摘一片,能和你相遇的概率只有1/n!那么小.我该是多么的幸运,才让你今天这么近地站在我面前. 相信我,我一定会把这亿万分之一的缘分变为永远.” 粉红的樱花漫天飞舞,妹子瞬间被 Vani 感动了.她轻轻地牵起了他的手,和他相依而 坐.这时,她突然看到

bzoj2721樱花——质因数分解

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2721 要推式子! 发现x和y一定都比 n! 大.不妨设 x = n!+k: 则1/x + 1/y = 1/ n! <=> ( n! + k + y ) / ( n! + k ) * y = 1 / n! <=> n! * y+ k * y= (n!)^2 + n! * k + n! * y <=> y = (n!)^2 / k + n! 所以( x, y ) 的个