bzoj 2721[Violet 5]樱花 数论

[Violet 5]樱花

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 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 }

 

posted @ 2017-12-24 15:20  Kaiser-  阅读(340)  评论(0编辑  收藏  举报