zoukankan      html  css  js  c++  java
  • hdu3187 HP Problem

    Problem Description
    In mathematics, the greatest common divisor (gcd), of two non-zero integers, is the largest positive integer that divides both two numbers without a remainder. For example, gcd( 10, 15 ) = 5, gcd( 5, 4 ) = 1. If gcd( k, n ) == 1 , then we say k is co-prime to n ( also , n is co-prime to k ), the totient function H(n) of a positive integer n is defined to be the number of positive integers not greater than n that are co-prime to n. In particular H(1) = 1 since 1 is co-prime to itself (1 being the only natural number with this property). For example, H (9) = 6 since the six numbers 1, 2, 4, 5, 7 and 8 are co-prime to 9. Also, we define the number of different prime of n is P (n). For example, P (4) = 1 (4 = 2*2), P (10) = 2(10 = 2*5), P (60) = 3(2*2*3*5). Now, your task is, give you a positive integer n not greater than 2^31-1, please calculate the number of k (0 < k < 2^31) satisfied that H (k) = n and P (k) <= 3(So we called HP Problem).
     
    Input
    Each line will contain only one integer n. Process to end of file.
     
    Output
    For each case, output the answer in one line.
     
    Sample Input
    6
     
    Sample Output
    4

    思路:给定n为在[1,2^31-1]范围内有多少个数满足 H(k)=n&& P(k)<=3;

    H(k)为k的欧拉函数;P(K)为k中所含质因子的种类个数;

    欧拉公式:如果k=p1^q1 *P2^q2*....*pm^qm;

    则H(k)=k*(p1-1)*(p2-1)...(pm-1)/(p1*p2*p3*p4...pm)

    如果已知H(k)以及k中质因子(p1, p2, p3, p4,..pm)则可以唯一确定一个k=H(k)*(p1*p2*...*pm)/((p1-1)*(p2-1)...*(pm-1))

    于是对于n,如果找到了质因子集合{p1,p2,...,pm}( m<=3)则等于找到了一个k;

    同时这样的质因子集合满足

    n%(pi-1)==0&&n 不含集合外的其他质因子;同时求得的K应小于2^31;

    由于m<=3可以枚举具有上述性质的质因子集合来得到答案;

    n为1时,有2个,H(1)=1这种特殊情况要考虑。

    (真心看不懂啊……)

    View Code
    #include<stdio.h>
    #include<queue>
    #include<string.h>
    #include<math.h>
    #include<stdlib.h>
    #include<memory>
    #include<map>
    #include<set>
    #include<vector>
    #include<algorithm>
    #include<malloc.h>
    #include<iostream>
    using namespace std;
    typedef __int64 ll;
    #define N 100000
    #define M_F 1000
    const ll base=2147483648;
    int tag[N];
    ll prime[N/10],cnt;
    ll p[M_F],q[M_F],num;
    ll a[M_F],m;
    ll ans,n,pr[10],t;
    void get_prime()
    {
        int i,j;
        memset(tag,0,sizeof(tag));
        for(i=2;i*i<N;i++)
        if(!tag[i])
        {
            for(j=2;j*i<N;j++)
            tag[j*i]=1;
        }
        for(i=2,cnt=0;i<N;i++)
        if(tag[i]==0)prime[cnt++]=i;
    }
    
    void factor()
    {
        int i;
        ll tmp=n;
        for(num=0,i=0;i<cnt&&prime[i]*prime[i]<=n;i++)
        if(n%prime[i]==0)
        {
            p[num]=prime[i];
            q[num]=0;
            while(n%prime[i]==0)
            {
                q[num]++;
               n/=prime[i];
            }
            num++;
        }
        if(n>1)
        {
            p[num]=n;
            q[num++]=1;
        }
        n=tmp;
    }
    
    int Is_Ok(ll cur)
    {
        int i;
        cur++;
        for(i=0;i<cnt&&prime[i]*prime[i]<=cur;i++)
        if(cur%prime[i]==0)return 0;
        return 1;
    }
    
    void dfs(ll cur,int idx)
    {
        ll tmp=1;
        if(idx>=num)
        {
            if(Is_Ok(cur))a[m++]=cur;
            return ;
        }
        for(int i=0;i<=q[idx];i++)
        {
            dfs(cur*tmp,idx+1);
           tmp=tmp*p[idx];
       }
    }
    
    int judge()
    {
        ll ret,tmp;
       ret=n;
       int i;
        for(i=0;i<t;i++)
        {
            if(ret%(pr[i]-1))return 0;
            else ret/=(pr[i]-1);
        }
        for(i=0;i<t;i++)
        {
        ret=ret*pr[i];
        if(ret>=base||ret<0)return 0;
        }
        //tmp=ret;
        ret=n;
        for(i=0;i<t;i++)
        {
            ret/=(pr[i]-1);
        }
        for(i=0;i<t;i++)
        while(ret%pr[i]==0)ret/=pr[i];
        //if(ret==1)cout<<tmp<<endl;
        return (ret==1);
    }
    
    void dfs1(int idx,int k)
    {
        if(k>3)return ;
        else
       {
            if(k)
            {
                t=k;
                ans+=judge();
            }
            int i;
            for(i=idx;i<m;i++)
             {
                 pr[k]=a[i]+1;
                 dfs1(i+1,k+1);
             }
        }
    }
    
    int main()
    {
       get_prime();
       while(scanf("%I64d",&n)!=EOF)
       {
    
        factor();
        m=0;
        dfs(1,0);
         ans=0;
        dfs1(0,0);
        if(n==1)ans++;
        printf("%I64d\n",ans);
        }
    return 0;
    }
  • 相关阅读:
    Jetty 的工作原理以及与 Tomcat 的比较
    基于Tengine的反向代理详细配置
    mysql定时脚本(event),类似oracle的job
    mysql 强制走索引
    如何检查mysql中建立的索引是否生效的检测方法及相关参数说明
    MySQL查询不使用索引汇总
    [大牛翻译系列]Hadoop 翻译文章索引
    [牛感悟系列]JAVA(1)理解JAVA垃圾回收
    [大牛翻译系列]Hadoop系列性能部分完结
    [大牛翻译系列]Hadoop(22)附录D.2 复制连接框架
  • 原文地址:https://www.cnblogs.com/zlyblog/p/3032964.html
Copyright © 2011-2022 走看看