POJ2773---Happy 2006(容斥+二分)

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

二分区间上限mid,计算[1, mid]里与n互质的数个数,多次二分以后,mid的值就是第k个和n互质的数

/*************************************************************************
    > File Name: POJ2773.cpp
    > Author: ALex
    > Mail: [email protected]
    > Created Time: 2015年05月28日 星期四 19时36分15秒
 ************************************************************************/

#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>

using namespace std;

const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

vector <int> mst;

LL calc(LL high) {
    int size = mst.size();
    LL ans = 0;
    for (int i = 1; i < (1 << size); ++i) {
        int bits = 0;
        LL P = 1;
        for (int j = 0; j < size; ++j) {
            if (i & (1 << j)) {
                ++bits;
                P *= mst[j];
            }
        }
        if (bits & 1) {
            ans += high / P;
        }
        else {
            ans -= high / P;
        }
    }
    return high - ans;
}

int main() {
    LL m, k;
    while (cin >> m >> k) {
        mst.clear();
        LL tmp = m;
        for (int i = 2; i * i <= tmp; ++i) {
            if (tmp % i == 0) {
                mst.push_back(i);
                while (tmp % i == 0) {
                    tmp /= i;
                }
            }
        }
        if (tmp > 1) {
            mst.push_back(tmp);
        }
        LL ans = -1, mid;
        LL l = 1, r = (1LL << 60);
        while (l <= r) {
            mid = (l + r) >> 1;
            LL tmp = calc(mid);
            if (tmp >= k) {
                r = mid - 1;
                ans = mid;
            }
            else {
                l = mid + 1;
            }
        }
        printf("%lld\n", ans);
    }
}
时间: 2024-08-04 08:44:04

POJ2773---Happy 2006(容斥+二分)的相关文章

poj2773 Happy 2006(二分+容斥)

题目链接:点这里!!!! 题意: 给你两个整数m(1<=m<=1e6),k(1<=k<=1e8).求第k个与m互质的数是多少. 题解: 直接二分+容斥. 代码: #include<cstdio> #include<cstring> #include<iostream> #include<sstream> #include<algorithm> #include<vector> #include<bitse

POJ 2773 Happy 2006 (分解质因数+容斥+二分 或 欧几里德算法应用)

Happy 2006 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 10309   Accepted: 3566 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 a

POJ 2773 Happy 2006 二分+容斥(入门

题目链接:点击打开链接 题意: 输入n ,k 求与n互质的第k个数(这个数可能>n) 思路: solve(mid)表示[1,mid]中有多少个和n互质,然后二分一下最小的mid 使得互质个数==k solve(x) 实现: 与n互质的个数=所有数-与n不互质的数=所有数-(与n有一个因子-与n有2个因子的+与n有3个因子的) 状压n的因子个数,然后根据上面的公式容斥得到. #include <stdio.h> #include <iostream> #include <

POJ 2773 Happy 2006 (二分答案+容斥)

题目链接:http://poj.org/problem?id=2773 题意: 求第k个与m互质的数: 分析: 很明显随着数的增大与m互质的数就越多,因此我们可以二分答案, 中间需要用到容斥原理求[1,mid]内与m互质的数的个数: 代码如下: #include <iostream> #include <cstring> #include <cstdio> #include <vector> using namespace std; const int ma

BZOJ2440(全然平方数)二分+莫比乌斯容斥

题意:全然平方数是指含有平方数因子的数.求第ki个非全然平方数. 解法:比較明显的二分,getsum(int middle)求1-middle有多少个非全然平方数,然后二分.求1-middle的非全然平方数个数能够用总数减掉全然平方数个数.计算全然平方数的个数用容斥: 首先加上n/(2*2)+n/(3*3)+n/(5*5)+n/(7*7)...+...然后减掉出现两次的,然后加上三次的...奇加偶减.这就是mou的原型,用mou数组计算非常easy: 代码: /*****************

BZOJ2440(完全平方数)二分+莫比乌斯容斥

题意:完全平方数是指含有平方数因子的数.求第ki个非完全平方数. 解法:比较明显的二分,getsum(int middle)求1-middle有多少个非完全平方数,然后二分.求1-middle的非完全平方数个数可以用总数减掉完全平方数个数.计算完全平方数的个数用容斥: 首先加上n/(2*2)+n/(3*3)+n/(5*5)+n/(7*7)...+...然后减掉出现两次的,然后加上三次的...奇加偶减.这就是mou的原型,用mou数组计算很简单: 代码: /********************

codeforces B. Friends and Presents(二分+容斥)

题意:从1....v这些数中找到c1个数不能被x整除,c2个数不能被y整除! 并且这c1个数和这c2个数没有相同的!给定c1, c2, x, y, 求最小的v的值! 思路: 二分+容斥,二分找到v的值,那么s1 = v/x是能被x整除的个数 s2 = v/y是能被y整除数的个数,s3 = v/lcm(x, y)是能被x,y的最小公倍数 整除的个数! 那么 v-s1>=c1 && v-s2>=c2 && v-s3>=c1+c2就是二分的条件! 1 #incl

【二分+容斥+莫比乌斯反演】BZOJ2440 完全平方数

Description 求第k个没有完全平方因子的数,k<=1e9. Solution 这其实就是要求第k个µ[i](莫比乌斯函数)不为0的数. 然而k太大数组开不下来是吧,于是这么处理. 二分答案x,问题转化为求[1,x]间有多少个没有完全平方因子的数. 容斥,加上全部,减去一个质数的平方的倍数个数,加上两个质数乘积的平方的倍数个数... 然后发现,每个数的系数就是µ 这也说明了莫比乌斯的原理就是容斥,µ函数就是容斥系数 具体来说,对于每一个i<=sqrt(x),对于ans的贡献就是µ[i]

BZOJ 2440 完全平方数 (容斥+莫比乌斯反演+二分)

2440: [中山市选2011]完全平方数 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1673  Solved: 799 [Submit][Status][Discuss] Description 小 X 自幼就很喜欢数.但奇怪的是,他十分讨厌完全平方数.他觉得这些 数看起来很令人难受.由此,他也讨厌所有是完全平方数的正整数倍的数.然而 这丝毫不影响他对其他数的热爱. 这天是小X的生日,小 W 想送一个数给他作为生日礼物.当然他不能送一 个