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 }
  • 相关阅读:
    安卓adb
    图数据库学习
    分布式架构演进
    多活架构
    异地多活
    分布式CRDT
    技术架构的战略和战术原则
    分布式金融架构课笔记
    使用jackson进行json序列化时进行敏感字段脱敏(加密)或者忽略
    读书笔记《演进式架构》
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3247883.html
Copyright © 2011-2022 走看看