zoukankan      html  css  js  c++  java
  • POJ 2773 Happy 2006------欧几里得 or 欧拉函数。

    Happy 2006
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 8359   Accepted: 2737

    Description

    Two positive integers are said to be relatively prime to each other if the Great Common Divisor (GCD) is 1. For instance, 1, 3, 5, 7, 9...are all relatively prime to 2006. 

    Now your job is easy: for the given integer m, find the K-th element which is relatively prime to m when these elements are sorted in ascending order. 

    Input

    The input contains multiple test cases. For each test case, it contains two integers m (1 <= m <= 1000000), K (1 <= K <= 100000000).

    Output

    Output the K-th element in a single line.

    Sample Input

    2006 1
    2006 2
    2006 3
    

    Sample Output

    1
    3
    5
    

    Source

     
     
    这题,以前做的时候用欧几里得,枚举,2300ms,这次用现在的思路,欧拉来做500ms。
     
      1 /*
      2 题意:求第几个与N互素的数字。
      3       周期性问题。
      4       举例。
      5       5的互素有:1.2,3,4
      6       很明显:
      7       第一个互素是1
      8       第二个是    2
      9       ......
     10       第五个是    6=5+1;
     11       第六个是    8=6+2;
     12       这里就存在着周期T.
     13       1.需要注意对%==0 的时候的讨论。
     14       2.M的值可以为1.要特判。否则对后面的/法,有影响,会RE的。
     15       3.基本的思路也很简单,求出N的欧拉值,那么T就求出来了,然后
     16         求出它的素数因子,扫一遍,找到余数的那个互素数。
     17 */
     18 
     19 
     20 #include<iostream>
     21 #include<cstdio>
     22 #include<cstdlib>
     23 #include<cstring>
     24 using namespace std;
     25 
     26 
     27 int opl[1000003];
     28 int s[1000003];
     29 int prime[1000003],len;
     30 int f[1000],flen;
     31 
     32 
     33 void make_prime()//素数打表
     34 {
     35     int i,j;
     36     len=0;
     37     for(i=2;i<=1000000;i++)
     38     if(s[i]==false)
     39     {
     40         prime[++len]=i;
     41         for(j=i*2;j<=1000000;j=j+i)
     42         s[j]=true;
     43     }
     44 }
     45 
     46 void make_Euler()//欧拉函数[1,1000000]全部打表。
     47 {
     48     int i,j;
     49     make_prime();
     50     for(i=2;i<=1000000;i++)
     51     opl[i]=i;
     52     opl[1]=0;
     53     for(i=1;i<=len;i++)
     54     for(j=prime[i];j<=1000000;j=j+prime[i])
     55     opl[j]=opl[j]/prime[i]*(prime[i]-1);
     56 }
     57 
     58 void make_dEuler(int n)//素因子装在f[]
     59 {
     60     int i;
     61     flen=0;
     62     for(i=2;i*i<=n;i++)
     63     if(n%i==0)
     64     {
     65         while(n%i==0)
     66         n=n/i;
     67         f[++flen]=i;
     68     }
     69     if(n!=1)
     70     f[++flen]=n;
     71 }
     72 
     73 int make_ini(int n,int k1)
     74 {
     75     int i,j;
     76     int num=0;
     77     make_dEuler(n);
     78     memset(s,false,sizeof(s));
     79     for(i=1;i<=flen;i++)
     80     for(j=f[i];j<=n;j=j+f[i])
     81     s[j]=true;
     82     for(i=1;i<=n;i++)
     83     if(s[i]==false)
     84     {
     85         num++;
     86         if(num==k1)
     87         return i;
     88     }
     89 }
     90 
     91 int main()
     92 {
     93     int n,m,sum,k,k1,T;
     94     make_Euler();
     95     while(scanf("%d%d",&n,&m)>0)
     96     {
     97         if(n==1)//特判
     98         {
     99             printf("%d
    ",m);
    100             continue;
    101         }
    102         sum=0;
    103         T=opl[n];
    104         if(m%T==0)//!!~
    105         {
    106             sum=sum+n*((m-1)/T);
    107             sum=sum+make_ini(n,T);
    108         }
    109         else
    110         {
    111             sum=sum+n*(m/T);
    112             sum=sum+make_ini(n,m%T);
    113         }
    114         printf("%d
    ",sum);
    115     }
    116     return 0;
    117 }
  • 相关阅读:
    面向领域的微服务架构
    java常用工具类
    java字节码解析
    详解 Java 内部类
    MongoDB配置教程
    oracle18c相关
    VBS编辑文件夹下所有excel文档
    oracle新增主键
    sqlldr加载字符问题
    ora-00257
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3247883.html
Copyright © 2011-2022 走看看