首页 > 其他 > 详细

一本通1624樱花

时间:2019-02-24 14:48:48      阅读:278      评论:0      收藏:0      [点我收藏+]

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

一本通1624樱花

原文:https://www.cnblogs.com/gaojunonly1/p/10426066.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!