Topic Links:
http://poj.org/problem?id=2773
Happy 2006
Time Limit: 3000MS |
|
Memory Limit: 65536K |
Total Submissions: 9131 |
|
Accepted: 3073 |
Description The positive integers is said to being relatively prime to all other if the great Common Divisor (GCD) is 1. For instance, 1, 3, 5, 7, 9...are-relatively prime to 2006.
Now your job is easy:for the given integer m, find the k-th element which was relatively prime to m when these elements ar e sorted in ascending order.
Input The input contains multiple test cases. For each test case, it contains integers m (1 <= m <= 1000000), K (1 <= k <= 100000000).Output Output the k-th element in a single line.Sample Input 2006 12006 22006 3
Sample Output 135
Source POJ monthly--2006.03.26,static |
[Submit] [Go back] [Status] [Discuss]
Topic Meaning:
The number of K-coprime with M
Problem Solving Ideas:
Two points + the principle of tolerance and repulsion
Two separate requirements of the number I, using the 1~i principle to find the number of M coprime between the numbers KK, if the kk<k expand the range, if the kk>k expand the scope, if Kk=k and gcd (i,m) =1 description just found, otherwise continue to narrow the scope.
Code:
#include <CSpreadSheet.h> #include <iostream> #include <cmath> #include <cstdio> #include <sstream> #include <cstdlib> #include <string> #include <string.h> #include <cstring># include<algorithm> #include <vector> #include <map> #include <set> #include <stack># include<list> #include <queue> #include <ctime> #include <bitset> #include <cmath># Define EPS 1e-6#define INF 0x3f3f3f3f#define PI acos ( -1.0) #define LL __int64#define ll long long#define Lson l,m, (RT<&L t;1) #define Rson m+1,r, (rt<<1) |1#define m 1000000007//#pragma comment (linker, "/stack:1024000000,1024000000") using namespace std; #define N 1000bool isp[n+10];int pri[n+10],pp[n+10],cnt,cnt0;int m,k;ll res;void init ()//number of prime numbers within 1000 {cnt=0; for (int i=1;i<=n;i++) isp[i]=true; for (int i=2;i<=n;i++) {if (Isp[i]) {pri[++cnt]=i; for (int j=i*2;j<=n;j+=i) Isp[j]=false; }}}void Cal (int cur)//cur decomposition factorization {cnt0=0; for (int i=1;pri[i]*pri[i]<=cur;i++) {if (!) ( Cur%pri[i])) {pp[++cnt0]=pri[i]; while (!) ( Cur%pri[i]) cur/=pri[i]; }} if (Cur!=1) pp[++cnt0]=cur;} void Dfs (ll hav,int cur,int num,ll va)//tolerant principle to find the number of numbers with M coprime and less than VA {if (cur>cnt0| | (HAV>VA)) return; for (int i=cur;i<=cnt0;i++) {ll temp=hav*pp[i]; if (num&1) res-=va/temp; else res+=va/temp; DFS (TEMP,I+1,NUM+1,VA); }}void Solve (ll cur)//Find out the number of 1~cur and M coprime {res=cur; for (int i=1;i<=cnt0;i++) {res-=cur/pp[i]; DFS (pp[i],i+1,2,cur); }}ll gcd (ll a,ll B)//Request greatest common divisor {if (a%b==0) return B; return gcd (b,a%b);} int main () {//freopen ("In.txt", "R", stdin); Freopen ("OUT.txt", "w", stdout); Init (); while (~SCANF ("%d%d", &m,&k)) {ll ans,l,r,mid; L=1,r= (1LL<<62LL); Initialize a very large number CAl (M); while (l<=r) {mid= (l+r) >>1; Solve (mid); ll Temp=res; Number//printf ("Mid:%i64d res:%i64d\n", mid,res); System ("pause"); if (temp<k)//amplification l=mid+1; else if (temp==k) {if (gcd (mid,m) ==1)//The last one is exactly the same as M coprime, stating exactly what {ans=m Id Break } r=mid-1; Otherwise, continue shrinking} else r=mid-1; } printf ("%i64d\n", ans); } return 0;}