我很憤怒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; }