POJ 2773 容斥原理
链接:
http://poj.org/problem?id=2773
题意:
给出两个数m,k,要求求出从1开始与m互质的第k个数。
题解:
二分一个答案mid,容斥统计出在区间[1,mid]中是m的质因子的倍数的数的个数ans,然后我们可以用mid-ans得到区间中有多少个与m互质的数,不断二分下去,直到得出答案。
代码:
31 ll n, k; 32 ll factor[MAXN], sz; 33 ll sum, mid; 34 35 void prime_factor(ll n) { 36 sz = 0; 37 for (ll i = 2; i*i <= n; i++) if (n%i == 0) { 38 factor[sz++] = i; 39 while (n%i == 0) n /= i; 40 } 41 if (n > 1) factor[sz++] = n; 42 } 43 44 void dfs(ll id, ll step, ll num) { 45 if (id == sz) { 46 if (step != 0) { 47 if (step & 1) sum += mid / num; 48 else sum -= mid / num; 49 } 50 return; 51 } 52 dfs(id + 1, step, num); 53 if (num*factor[id] <= mid) 54 dfs(id + 1, step + 1, num*factor[id]); 55 } 56 57 int main() { 58 while (cin >> n >> k) { 59 prime_factor(n); 60 ll l = k, r = 1e18, ans = l; 61 while (l <= r) { 62 mid = (l + r) / 2; 63 sum = 0; 64 dfs(0, 0, 1); 65 if (mid - sum >= k) r = mid - 1, ans = mid; 66 else l = mid + 1; 67 } 68 cout << ans << endl; 69 } 70 return 0; 71 }