一本通1624樱花

1624:樱花

时间限制: 1000 ms         内存限制: 524288 KB

【题目描述】

原题来自: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;

对于全部数据,1n106 。

 

sol:好一道坑人的普及题,表示我就是被坑爆的蒟蒻

随便拆一下式子可得

原式:1/x + 1/y = 1/n!
--> (x+y) / (x*y) = 1/n!
--> (x+y)*n! = x*y
--> x*n!+y*n! = x*y
--> x*y-x*n! = y*n!
--> x*(y-n!) = y*n!
--> x = (y*n!) / (y-n!)
易知 x>n!, y>n! 令y=n!+T
--> x = (n!+T)*n! / T
--> x = (n!*n!) / T + n!
就是求(n!*n!)的约数个数

然后我就暴力分解质因数,TLE。。。TLE。。。TLE。。。

/*
原式:1/x + 1/y = 1/n!
--> (x+y) / (x*y) = 1/n!
--> (x+y)*n! = x*y
--> x*n!+y*n! = x*y
--> x*y-x*n! = y*n!
--> x*(y-n!) = y*n!
--> x = (y*n!) / (y-n!)
易知 x>n!, y>n! 令y=n!+T
--> x = (n!+T)*n! / T
--> x = (n!*n!) / T + n!
就是求(n!*n!)的约数个数
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0'); return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int Mod=1000000007;
const int N=1000005;
int n;
bool Bo[N];
int Prim[N],Pos[N];
ll Ges[N];
inline void Get_Prime()
{
    int i,j;
    for(i=2;i<=n;i++)
    {
        if(!Bo[i])
        {
            Prim[++*Prim]=i; Pos[i]=*Prim;
        }
        for(j=1;j<=*Prim&&Prim[j]*i<=n;j++)
        {
            Bo[Prim[j]*i]=1;
            if(i%Prim[j]==0) break;
        }
    }
}
int main()
{
    int i,j;
    R(n);
    Get_Prime();
    for(i=2;i<=n;i++)
    {
        int oo=i;
        for(j=2;j<=sqrt(oo);j++) if(oo%j==0)
        {
            while(!(oo%j))
            {
                Ges[Pos[j]]++; oo/=j;
            }
        }
        if(oo>1) Ges[Pos[oo]]++;
    }
    for(i=1;i<=*Prim&&Prim[i]<=n;i++)
    {
        (Ges[i]<<=1)%=Mod;
    }
    ll ans=1;
    for(i=1;i<=*Prim&&Prim[i]<=n;i++)
    {
        ans=ans*(Ges[i]+1)%Mod;
    }
    Wl(ans);
    return 0;
}
/*
input
2
output
3

input
5
output
63

input
999998
output
501065738
*/
暴力

然后发现可以这样统计个数

 

for(i=1;i<=*Prim;i++)
{
    for(j=Prim[i];j<=n;j*=Prim[i])
    {
        Ges[i]+=1ll*n/j;
    }
    Ges[i]=(Ges[i]<<1)%Mod;
}

 

为我的智障默哀。。。

/*
原式:1/x + 1/y = 1/n!
--> (x+y) / (x*y) = 1/n!
--> (x+y)*n! = x*y
--> x*n!+y*n! = x*y
--> x*y-x*n! = y*n!
--> x*(y-n!) = y*n!
--> x = (y*n!) / (y-n!)
易知 x>n!, y>n! 令y=n!+T
--> x = (n!+T)*n! / T
--> x = (n!*n!) / T + n!
就是求(n!*n!)的约数个数
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0'); return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int Mod=1000000007;
const int N=1000005;
ll n;
bool Bo[N];
int Prim[N],Pos[N];
ll Ges[N];
inline void Get_Prime()
{
    int i,j;
    for(i=2;i<=n;i++)
    {
        if(!Bo[i])
        {
            Prim[++*Prim]=i; Pos[i]=*Prim;
        }
        for(j=1;j<=*Prim&&Prim[j]*i<=n;j++)
        {
            Bo[Prim[j]*i]=1;
            if(i%Prim[j]==0) break;
        }
    }
}
int main()
{
    ll i,j;
    R(n);
    Get_Prime();
    for(i=1;i<=*Prim;i++)
    {
        for(j=Prim[i];j<=n;j*=Prim[i])
        {
            Ges[i]+=1ll*n/j;
        }
        Ges[i]=(Ges[i]<<1)%Mod;
    }
    ll ans=1;
    for(i=1;i<=*Prim&&Prim[i]<=n;i++)
    {
        ans=ans*(Ges[i]+1)%Mod;
    }
    Wl(ans%Mod);
    return 0;
}
/*
input
2
output
3

input
5
output
63

input
999998
output
501065738
*/
View Code
posted @ 2019-02-24 14:15  yccdu  阅读(640)  评论(1编辑  收藏  举报