zoukankan      html  css  js  c++  java
  • BJOI2014 Euler

    Description

    已知$varphi (x)=y$,求最小的$x$

    Solution

    $$left{
    egin{aligned}
    varphi(x)=xprod_{i=1}^n frac{p_i-1}{p_i} \
    x=p_1^{q_1}p_2^{q_2}cdots p_n^{q_n}
    end{aligned}
    ight.$$

    化简得

    $$y=p_1^{q_1-1}p_2^{q_2-1}cdots p_n^{q_n-1}prod_{i=1}^n {p_i-1}$$

    枚举$y$中所有因数,找到所有的$p$,DFS组合所有$x$

    #pragma GCC optimize(2)
    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    using namespace std;
    long long T,y,ans,tot,p[1000000];
    inline long long read()
    {
        long long f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            w=(w<<1)+(w<<3)+ch-'0';
            ch=getchar();
        }
        return f*w;
    }
    bool check(long long x)
    {
        for(long long i=2;i*i<=x;i++)
            if(!(x%i))
                return false;
        return true;
    }
    bool split(long long cnt,long long now)
    {
        while(!(now%p[cnt]))
            now/=p[cnt];
        return now==1;
    }
    void dfs(long long cnt,long long now,long long ret)
    {
        if(cnt>tot||ret>ans)
            return;
        dfs(cnt+1,now,ret);
        if(!(now%(p[cnt]-1)))
        {
            if(split(cnt,now/(p[cnt]-1)))
                ans=min(ans,ret/(p[cnt]-1)*p[cnt]);
            now/=(p[cnt]-1);
            dfs(cnt+1,now,ret/(p[cnt]-1)*p[cnt]);
            while(!(now%p[cnt]))
            {
                now/=p[cnt];
                dfs(cnt+1,now,ret/(p[cnt]-1)*p[cnt]);
            }
        }
    }
    bool cmp(long long a,long long b)
    {
        return a>b;
    }
    int main()
    {
        T=read();
        for(;T;T--)
        {
            tot=0;
            y=read();
            if(y==1)
            {
                puts("1");
                continue;
            }
            ans=1ll<<60;
            for(long long i=1;i*i<=y;i++)
                if(!(y%i))
                {
                    if(check(i+1ll))
                        p[++tot]=i+1ll;
                    if(i*i==y)
                        continue;
                    if(check(y/i+1ll))
                        p[++tot]=y/i+1ll;
                }
            sort(p+1,p+tot+1,cmp);
            dfs(1,y,y);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    Euler
  • 相关阅读:
    文件操作
    set集合,深浅拷贝
    is 和 == 区别 id()函数
    字典
    列表
    基本数据类型
    第十二章 if测试和语法规则
    第十一章 赋值、表达式和打印
    第十章 python语句简介
    第九章元组、文件及其他
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/13356562.html
Copyright © 2011-2022 走看看