bzoj 2721[Violet 5]樱花 数论
[Violet 5]樱花
Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 671 Solved: 395
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
Sample Output
HINT
题解:
上面废话许多。
设n!=z,y=z+d
1/x+1/y=1/z
1/x+1/(z+d)=1/z
(x+z+d)/(x*z+dx)=1/z
z(x+z+d)=x*z+dx
z^2+dz=dx
x=z^2/d+z
发现就是求z^2的约数个数
很有道理
1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 7 #define mod 1000000007 8 #define ll long long 9 #define N 1000007 10 using namespace std; 11 int read() 12 { 13 int x=0;char ch=getchar(); 14 while(ch<'0'||ch>'9')ch=getchar(); 15 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 16 return x; 17 } 18 19 int n,cnt; 20 ll ans=1; 21 int pri[N],mn[N],num[N]; 22 bool flag[N]; 23 24 void getpri() 25 { 26 for(int i=2;i<=n;i++) 27 { 28 if(!flag[i])pri[++cnt]=i,mn[i]=cnt; 29 for(int j=1;pri[j]*i<=n&&j<=cnt;j++) 30 { 31 flag[pri[j]*i]=1;mn[pri[j]*i]=j; 32 if(i%pri[j]==0)break; 33 } 34 } 35 } 36 void cal(int x) 37 { 38 while(x!=1) 39 { 40 num[mn[x]]++; 41 x/=pri[mn[x]]; 42 } 43 } 44 int main() 45 { 46 n=read(); 47 getpri(); 48 for(int i=1;i<=n;i++)cal(i); 49 for(int i=1;i<=cnt;i++) 50 ans=ans*(num[i]*2+1)%mod; 51 printf("%lld\n",ans); 52 }