http://poj.org/problem?id=2773
To tell the truth about this problem. It's not happy, okay?
It seems that the Euler function can also be used to solve the problem, but just learned the principle of tolerance and two points, use this solution.
Troubleshooting: Required output [1,m] and M coprime the number of K, first hit the table, find all the M factorization, and then realize with two points, the first interval for [1,2^60], using the principle of tolerance to find the interval [1,mid] The number of primes within the T, continue to carry out two points, until the search interval [l,r] The number of the inner prime number T equals K,mid=l=r, then the L is the first K and M coprime.
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespaceStd;typedefLong Longll;#defineN 1000005Vector<int>v;voidGetprime (intN//Number of N-l,r in [+]{v.clear (); //Filter Prime Numbers for(intI=2; i*i<=n;i++) { if(n%i==0) {v.push_back (i); while(n%i==0) n/=i; } } if(n>1) V.push_back (n);} ll solve (ll N) {//a binary solution for the principle of tolerance and repulsion intlen=v.size (); ll Res=0; for(intI=1;i< (1<<len); i++) { intCnt=0; ll Val=1; for(intj=0; j<len;j++) { if(i& (1<<j)) {CNT++; Val*=V[j]; } } if(cnt&1)//If an odd item is additive, the even item is subtractedres+=n/Val; Elseres-=n/Val; } returnN-Res;}intMain () {intm,k; while(~SCANF ("%d%d",&m,&K)) {getprime (M); ll L=1, R= (1ll<< -), mid,t; while(l<r) {Mid= ((l+r) >>1); T=solve (mid); if(t>=K) R=mid; ElseL=mid+1; } printf ("%i64d\n", L); } return 0;}
POJ 2773 Happy 2006# Prime number screening + tolerance principle + two points