BZOJ2721: [Violet 5]樱花

BZOJ2721: [Violet 5]樱花

Description

Input

Output

 

Sample Input

 1439

Sample Output

 102426508

HINT


题解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;
}

 

posted @ 2018-08-16 23:44  符拉迪沃斯托克  阅读(460)  评论(0编辑  收藏  举报
Live2D