1. 程式人生 > >【bzoj2721】[Violet 5]櫻花

【bzoj2721】[Violet 5]櫻花

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
#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

【bzoj2721】[Violet 5]櫻花