• 【BZOJ-3643】Phi的反函数 数论 + 搜索


    3643: Phi的反函数

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 141  Solved: 96
    [Submit][Status][Discuss]

    Description

    Input

    Output

    Sample Input

    4

    Sample Output

    5

    HINT

    Source

    By Zky

    Solution

    首先答案和N一定是同阶的,所以,可以很暴力的线筛扫一遍求解。

    然后根据欧拉函数的式子,我们实际上是可以爆搜的。

    爆搜他的质因子然后去凑答案,加最优性剪枝就可以跑过。

    最关键的是依据欧拉函数的定义式找到规律!

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    #define LL long long
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define MAXN 5100000
    int X,N;
    int prime[MAXN],flag[MAXN],cnt;
    void Getprime()
    {
        flag[1]=1; cnt=0;
        for (int i=2; i<=N; i++)
            {
                if (!flag[i]) prime[++cnt]=i;
                for (int j=1; j<=cnt && prime[j]*i<=N; j++)
                    {
                        flag[i*prime[j]]=1;
                        if (prime[j]%i==0) break;
                    }
            }
    }
    LL ans=(1LL<<30);
    LL sqr(LL x) {return (LL)x*x;}
    bool check(int x) 
    {
    //  if (flag[x]) return 0;
        for (int i=1; sqr(prime[i])<=x && i<=cnt; i++) if (x%prime[i]==0) return 0;
        return 1;
    }
    void DFS(int dep,LL sum,LL x,int last)
    {
        if (sum>=ans) return;
        if (x==1) {ans=sum; return;}
        if (check(x+1) && sqr(x)>X) ans=min(ans,sum*(x+1));
        for (int i=last+1; (prime[i]-1)<=x && sqr(prime[i]-1)<=X; i++)
            if (!(x%(prime[i]-1)))
                {
                    LL xx=(LL)x/(prime[i]-1),summ=(LL)sum*prime[i];
                    DFS(dep+1,summ,xx,i);
                    while (!(xx%prime[i])) xx=(LL)xx/prime[i],summ=(LL)summ*prime[i],DFS(dep+1,summ,xx,i);
                }
    }
    int main()
    {
        X=read();  N=int(sqrt(X))+1010;
        if (X==1) {puts("1"); return 0;}
        Getprime();
        DFS(1,1LL,(LL)X,1);
        printf("%lld
    ",ans==(1LL<<30)? -1:ans);
        return 0;
    }

    仔细思考一下应该是可以想到的。

  • 相关阅读:
    本地文件上传到Linux服务器
    进阶线路
    process.env.NODE_ENV
    Docker 实践备忘录
    Sae配置Java数据库连接
    Java实现微信菜单json字符串拼接
    spring+hibernate+jpa+Druid的配置文件,spring整合Druid
    根据当前节点获取所有上层结构的组织(递归算法)
    实现左右两边用户添加、删除、调位置(上下移动)、排序等的功能
    Dom4j解析Xml文件,Dom4j创建Xml文件
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5943390.html
Copyright © 2020-2023  润新知