Happy 2006
Time Limit: 3000MS |
|
Memory Limit: 65536K |
Total Submissions: 10309 |
|
Accepted: 3566 |
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
Title Link: http://poj.org/problem?id=2773
The main idea: to find the number of K and M coprime
Title Analysis: Two methods, the main method is decomposition factorization + two + tolerance, 0ms, first on the M decomposition factorization, and then two points, two time-sharing with the capacity to calculate 1 to the current number and m not coprime number, and then with M minus, is the number of M coprime.
#include <cstdio> #include <cstring> #define LL long longint Const MAX = 1e6 + 6;int fac[max];int N, K, cnt;ll s Um;void get_factor (int x) {cnt = 0; for (int i = 2; i <= x; i++) {if (x% i = = 0) fac[cnt + +] = i; while (x% i = = 0) x/= i; } if (x > 1) fac[cnt + +] = x;} void DFS (int pos, int num, LL cur, ll x) {if (pos = = cnt) {if (cur = = 1) return; if (num & 1) sum + = X/cur; else sum-= x/cur; Return } DFS (pos + 1, num, cur, x); DFS (pos + 1, num + 1, cur * fac[pos], x); return;} LL Cal (ll mid) {sum = 0; DFS (0, 0, 1, mid); return sum;} int main () {while (scanf ("%d%d", &n, &k)! = EOF) {get_factor (n); ll L = 0, R = 1e17, mid; while (L <= r) {mid = (L + r) >> 1; if (Mid-cal (mid) < K) L = mid + 1; else R = Mid-1; } printf ("%lld\n", L); }}
The second method utilizes the Euclidean algorithm, gcd (A, b) = gcd (b, a% b), so that a = km + I,B = m are:
gcd (km + i, m) = gcd (i, m), indicating that the number of M coprime m is periodic, so that the number is less than M and with M coprime of CNT, the first I is AI, then the m*cnt+i is M*cnt+ai, and secondly to note that K is evenly divisible by the CNT, which is actually a[ CNT] instead of a[0], this method ran 2400ms+
#include <cstdio>int Const MAX = 1e6 + 5;int a[max];int gcd (int a, int b) {while (b) { int tmp = A; A = b; b = tmp% B; } return A;} int main () { int m, K; while (scanf ("%d%d", &m, &k)! = EOF) { if (k = = 1) { printf ("1\n"); Continue; } if (m = = 1) { printf ("%d\n", k); Continue; } int cnt = 1; for (int i = 1; I <= m; i++) if (gcd (i, m) = = 1) a[cnt + +] = i; CNT--; If (k% cnt = = 0) printf ("%d\n", (k/cnt-1) * m + a[cnt]); else printf ("%d\n", (k/cnt) * m + a[k% cnt]);} }
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
POJ 2773 Happy 2006 (decomposition factorization + repulsion + binary or Euclidean algorithm application)