我很愤怒c++
求方程 1/X+1/Y=1/(N!) 的正整数解的组数,其中N≤10^6。spa
解的组数,应模1e9+7。code
输入格式:get
输入一个整数Nit
输出格式:io
输出答案class
输入样例#1:im
1439统计
输出样例#1:di
102426508
极其恶心的一道题...
看到这种题确定是须要化简式子的,由于出题人不会好到给你一个好作的式子
\[\frac{1}{x}+\frac{1}{y}=\frac{1}{n!}\]
\[\frac{x+y}{xy}=\frac{1}{n!}\]
\[xy=(n!)\times (x+y)\]
一个骚操做,两边同时加上\((n!)^2\),为何,由于方便因式分解...
\[(n!)^2-(n!)\times (x+y)+xy=(n!)^2\]
而后因式分解
\[(n!-x)\times (n!-y)=(n!)^2\]
令\(a=(n!-x),b=(n!-y)\),由于\((n!)^2\)是肯定的,因此肯定了\(a\),就能够肯定\(b\),也就能够肯定\(x,y\)了
那么a的方案数是多少?由于\(a\)是\((n!)^2\)的因子,因此\(a\)的取值的方案数就是\((n!)^2\)的因子的方案数
而后根据惟一分解定理
\[n!=p_1^{c_1}\times p_2^{c_2}\times ...\times p_m^{c_m}\]
\[(n!)^2=p_1^{2\times c_1}\times p_2^{2\times c_2}\times ...\times p_m^{2\times c_m}\]
因为每一个质因子\(p_i\)都有\(2\times c_i+1\)种取值,因此
\[ans=(2\times c_1+1)\times (2\times c_2 +1)\times ...\times(2\times c_m+1)\]
那么最后问题就转化成了对\(n!\)进行分解质因数,并求质因数的个数
暴力对\(1-n\)每一个数分解质因数,再合并复杂度太高,为\(O(n\sqrt n)\)
因为\(n!\)的每一个质因子都不超过n,因此咱们能够预处理\(1-n\)内全部质数p,再考虑\(n!\)内一共有多少个质因子p
咱们能够对于在线性筛质数的过程当中同时处理一下n之内每一个数的最小质因子\(p\),而后统计这个数的贡献,在\(1-n\)中至少包含一个质因子\(p\)的有\(\lfloor\frac{n}{p}\rfloor\),至少包含两个质因子p的有\(\lfloor\frac{n}{p^2}\rfloor\)...
那么\(n!\)中质因子\(p\)的个数就是
\[\lfloor\frac{n}{p}\rfloor+\lfloor\frac{n}{p^2}\rfloor+...+\lfloor\frac{n}{p^{log_{p}{n}}}\rfloor\]
对于每一个质因子,咱们只须要\(log\ n\)的时间来求解,因此总复杂度是\(O(n\ log\ n)\)的
#include<bits/stdc++.h> #define rg register #define il inline #define Min(a,b) ((a)<(b)?(a):(b)) #define Max(a,b) ((a)>(b)?(a):(b)) #define lol long long #define in(i) (i=read()) using namespace std; const lol N=1e6+10,mod=1e9+7; lol read() { lol ans=0,f=1; char i=getchar(); while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();} while(i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+i-'0',i=getchar(); return ans*=f; } lol n,cnt,ans=1; lol g[N],prime[N],c[N]; void init() { memset(g,0,sizeof(g)); for(int i=2;i<=n;i++) { if(!g[i]) g[i]=i,prime[++cnt]=i; for(int j=1;j<=cnt && i*prime[j]<=n;j++) { g[i*prime[j]]=prime[j]; if(i%prime[j]==0) break; } } } int main() { in(n); init(); for(int i=1;i<=n;i++) for(int j=i;j!=1;j/=g[j]) c[g[j]]++; for(int i=1;i<=n;i++) ans=ans*(c[i]*2+1)%mod; cout<<ans<<endl; }