BZOJ2721: [Violet 5]樱花
Description
.gif)
Input
.gif)
Output
.gif)
Sample Input
1439
Sample Output
102426508
HINT
.gif)
题解Here!
一道恶心数论题。。。
这个分母看得很烦人,于是将方程左边通分:$$\frac{x+y}{xy}=\frac{1}{n!}$$
十字相乘:$$n!(x+y)=xy$$
移项:$$xy-n!(x+y)=0$$
两边同时加上$(n!)^2$得:$$(n!)^2-n!(x+y)+xy=(n!)^2$$
左边因式分解:$$(x-n!)(y-n!)=(n!)^2$$
设$a=x-n!,b=y-n!$,则有:$$ab=(n!)^2$$
由唯一分解定理可知:$$n!=p_1^{num_1}\times p_2^{num_2}\times...\times p_k^{num_k}$$
那么有:$$(n!)^2=p_1^{2num_1}\times p_2^{2num_2}\times...\times p_k^{2num_k}$$
也就是:$$ab=p_1^{2num_1}\times p_2^{2num_2}\times...\times p_k^{2num_k}$$
因为$n!$是确定的,所以确定了$a,b$,就能确定$x,y$。
并且只要确定了$a$,就能确定$b$!
我们知道,$a$是$(n!)^2$的因式。
那么$a$的个数为:$$(2num_1+1)(2num_2+1)...(2num_k+1)$$
于是最后的答案即为:$$(2num_1+1)(2num_2+1)...(2num_k+1)\mod (10^9+7)$$
线性筛搞一遍,然后把$num_i$全部计算出来,最后统计答案即可。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 1000010
#define MOD 1000000007
using namespace std;
int n;
int k=0,prime[MAXN],num[MAXN],val[MAXN];
bool np[MAXN];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
void make(){
int m=n;
for(int i=2;i<=m;i++){
if(!np[i]){
prime[++k]=i;
val[i]=i;
}
for(int j=1;j<=k&&prime[j]*i<=m;j++){
np[prime[j]*i]=true;
val[prime[j]*i]=prime[j];
if(i%prime[j]==0)break;
}
}
for(int i=1;i<=m;i++)
for(int j=i;j!=1;j/=val[j])
num[val[j]]++;
}
void work(){
long long ans=1;
for(int i=1;i<=n;i++)ans=(long long)1LL*ans*((num[i]<<1)+1)%MOD;
printf("%lld\n",ans);
}
int main(){
n=read();
make();
work();
return 0;
}

浙公网安备 33010602011771号