樱花(信息学奥赛一本通 1624)
Posted ljy-endl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了樱花(信息学奥赛一本通 1624)相关的知识,希望对你有一定的参考价值。
【题目描述】
原题来自:HackerRank Equations
求不定方程: 1/x + 1/y = 1/n!
的正整数解 (x,y)的数目。
【输入】
一个整数 n。
【输出】
一个整数,表示有多少对 (x,y) 满足题意。答案对 109+7 取模。
【输入样例】
2
【输出样例】
3
【提示】
样例说明
共有三个数对 (x,y) 满足条件,分别是 (3,6),(4,4) 和 (6,3)。
数据范围与提示:
对于 30% 的数据,n≤100;
对于全部数据,1≤n≤106 。
(这里不得不吐糟一下,书上把题目打错了啦,n!写成了n,害得我还以为这道题可以暴力去做,结果光荣的爆零了(▼⊿▼))
首先呢就是用数学方法把这个不定方程变化一下,令y=n+a(x、y肯定比n大啦,可以自己推导一下),很容易就得到了 x = (n!*n!) / a+ n!
那么因为n!为整数、x也为整数,所以(n!*n!) / a一定也为整数。那要求x的个数的话就是要求满足(n!*n!) / a为整数的a的个数啦
所以说这道题很快就转化成了一道求约数个数的题目。
然后就是唯一分解定理和约数个数定理...
上代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e6+1,M=1e9+7; 4 int a[N],n,v[N],cnt,b[N],num[N];//b[x]表示x的最小质因子是质数中的第几号 5 long long ans=1; 6 int read() 7 8 int x=0,f=1; 9 char ch=getchar(); 10 while(ch<‘0‘||ch>‘9‘) 11 12 if(ch==‘-‘) f=-1; 13 ch=getchar(); 14 15 while(ch>=‘0‘&&ch<=‘9‘) 16 17 x=x*10+ch-‘0‘; 18 ch=getchar(); 19 20 return x*f; 21 22 void write(int x) 23 24 if(x<0) 25 26 putchar(‘-‘); 27 x=-x; 28 29 if(x>9) write(x/10); 30 putchar(x%10+‘0‘); 31 32 void pre() 33 34 for(int i=2;i<=1000000;i++) 35 36 if(!v[i])a[++cnt]=i,b[i]=cnt; 37 for(int j=1;j<=cnt&&a[j]*i<=1000000;j++) 38 39 v[i*a[j]]=1;b[i*a[j]]=j; 40 if(i%a[j]==0)break; 41 42 43 44 void ff(int x) 45 46 while(x!=1) 47 48 num[b[x]]++;//num[i]表示i这个序号代表的质因子出现的次数(也就是b[i]的幂的次数啦) 49 x/=a[b[x]];//x不断更新 50 51 52 int main() 53 54 55 n=read(); 56 pre(); 57 for(int i=2;i<=n;i++) 58 ff(i); 59 for(int i=1;i<=cnt;i++) 60 ans=ans*(num[i]*2+1)%M; 61 printf("%lld",ans); 62 return 0; 63
//参考:这位大佬讲的hin好,点击%大佬的博客
以上是关于樱花(信息学奥赛一本通 1624)的主要内容,如果未能解决你的问题,请参考以下文章