2773 Happy 2006 //欧拉函数的应用

Happy 2006
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 5258   Accepted: 1576

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

POJ Monthly--2006.03.26,static

 

 

/* //这个题可以分段做,在到m之间与m互素的数有m的欧拉个, //(第一反应把以前用过的oula函数调了出来,)同样可推出m+1到2m之间, //n*m+1到(n+1)*m之间与m互素的个数也相同,,因为若k与m互素, //则k+n*m与m也互素,因为(n*m+K)%m=k%m;,,从而这题只要先求出-m之间与m 互素的数res[i]和总个数存入res[0], //若a[0]<k;,则为((k-1)/res[0])*m+res[k%res[o]],这里有一个小问题有注意是当res%res[0]==0时k=res[0]; //那么剩下的问题就是求1-m之间与m互素的数了,因为m<1000000如果暴力的话可能会超时,,, //求互素的问题这时就要想到伟大的欧拉大牛了,他证明了任何一个数可以分拆成N个素数的T[k]次方的积, //即n=p1^t1*…*pk^tk,,,从而再通过筛法筛掉m的素因子倍数的数,则剩下的就是和m互素的数了,存入数组res[]就OK了 //其实因为(n*m+K)%m=k%m,所以先求1-m内与m互质的数,然后这些数+(n*m),就是其他与m互质的数了,而那个n又可以根据 //(n*m+K)%m=k%m这条公式得到,首先是求出m的欧拉函数值phi[m],可知区间[1, m - 1]中有phi[m]个数与m互质。 //同样,在区间[n*m + 1, (n + 1) * m]中必然也有phi[m]个数与m互质,并且这phi[m]个数与[1 - m - 1]的phi[m]个数是"一一对应"的 //因此就可以先求1-m的互质数,然后再加上n*m就可以求第k个了这个时间很快47ms*/ #include<cstdio> #include<cstring> #include<cmath> const int N = 1000010; bool is_p[N];//判断素数 int prime[N];//存素数 int p[N]; int res[N]; int n,k; void getpri() { memset(is_p,true,sizeof(is_p)); int num=0; prime[++num]=2; for(int i=3;i*i<=N;i+=2) if(is_p[i]) { for(int j=i*i;j<N;j+=i) is_p[j]=false; } for(int i=3;i<N;i+=2) if(is_p[i]) prime[++num]=i; prime[0]=num; } void getp(int n)//求因子 { int num=0; for(int i=1;prime[i]*prime[i]<=n;i++) { if(n%prime[i]==0) { p[++num]=prime[i]; while(n%prime[i]==0) n=n/prime[i]; } } if(n>1) p[++num]=n; p[0]=num; } void eular()//晒互质数 { getp(n); memset(is_p,true,sizeof(is_p)); for(int i=1;i<=p[0];i++) { for(int j=p[i];j<=n;j+=p[i]) is_p[j]=false;//把m的因子和它的因子的倍数都晒去,剩下的就是互质的了 } int num=0; res[++num]=1; for(int i=2;i<=n;i++) if(is_p[i]) res[++num]=i; res[0]=num; } int main() { getpri(); __int64 ans; while(scanf("%d%d",&n,&k)!=EOF) { eular();//求出所有跟m互质的数 int x=k%res[0]; if(x==0) x=res[0]; __int64 y=(k-1)/res[0]; ans=y*n+res[x]; printf("%I64d/n",ans); } return 0; }

你可能感兴趣的:(Integer,ini,input,each,output)