• 一本通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('
    ')
    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('
    ')
    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
  • 相关阅读:
    Redis使用初步
    Servlet Java Web开发(3.1) request response
    TcpClient例子(2)更robust的程序
    C#多线程之ManualResetEvent,Thread,ThreadPool,BackgroudWoker
    使用TcpClient的例程
    C#中多线程修改UI
    C# 多线程之异步回调
    Servlet Java Web开发(3) request response和编码
    Eclipse 和MyEclipse下Servlet Java Web开发(2)
    Eclipse 和MyEclipse下Servlet Java Web开发(1)
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/10426066.html
Copyright © 2020-2023  润新知