POJ 2773 容斥与二分

来源:互联网 发布:vm12安装mac 编辑:程序博客网 时间:2024/04/27 19:44
#include <cstdio>#include <cstring>const int maxn = 1E6 + 10;int p[maxn], cnt, m, k;void init(){cnt = 0;for (int i = 2; i * i <= m; i++)if (m % i == 0){p[cnt++] = i;while (m % i == 0) {m /= i;}}if (m != 1) p[cnt++] = m;}long long cal(long long n){long long res = 0;for (int i = 1; i < (1 << cnt); i++){long long bit = 0, sum = 1;for (int j = 0; j < cnt; j++)if (i & (1 << j)) bit++, sum *= p[j];res += (bit & 1 ? -1 : 1) * n / sum;}return n + res;}int main(int argc, char const *argv[]){while (~scanf("%d%d", &m, &k)){init();long long l = 1, r = 1LL << 60, mid, tmp;while (r - l > 0){mid = (l + r) >> 1;tmp = cal(mid);if (tmp >= k) r = mid;else l = mid + 1;}printf("%lld\n", l);}return 0;}


求第K个与M互素的数。

数据范围超大,显然二分。

令F(x)为与M互素且小于X的数的总数,则F(x)=X-X/(1个因数) + X/(2个因数) -....;

具体实现可以使用二进制枚举子集来实现。

0 0
原创粉丝点击