【bzoj2721】[Violet 5]櫻花
阿新 • • 發佈:2018-05-26
n! tmp 代碼 include 什麽 TP ctime col style
題目傳送門: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 #definebzoj2721max(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】[Violet 5]櫻花