第k个互质数(二分 + 容斥)

描述两个数的a,b的gcd为1,即a,b互质,现在给你一个数m,你知道与它互质的第k个数是多少吗?与m互质的数按照升序排列。

输入
输入m ,k (1<=m<=1000000;1<=k<=100000000)
输出
输出第k个数。
样例输入
10 1
10 2
10 3

样例输出

1
3
7

首先对m进行质因数分解,求出m有哪些质因数,然后用容斥求[1, mid]内与m互质的数有多少个。

判断的时候,[1,mid]之间与m互质的数的数量 = mid - (包含一个质因子的数的个数)+ (包含2个质因子的书的个数)-(包含3个质因子的数的个数)+ (包含4个质因数的数的个数)……

 1 #include <cstdio>
 2 // 对n进行素因子分解, fac[0]记录因子个数;
 3 int fac[20];
 4 void Div(int n) {
 5     int k = 0;
 6     for(int i = 2; i * i <= n; ++i){
 7         if(n % i == 0) fac[++k] = i;
 8         while(n % i == 0) n /= i;
 9     }
10     if(n > 1) fac[++k] = n;
11     fac[0] = k;
12 }
13 // 计算[1, n]内与m互质的数的个数
14 int que[1<<10];
15 int Count(int n, int m) {
16     int g = 0, sum = n;
17     que[++g] = 1;
18     for(int i = 1; i <= fac[0]; ++i){
19         int t = g;
20         for(int j = 1; j <= g; ++j){
21             que[++t] = que[j] * fac[i] * -1;
22             sum += n / que[t];
23         }
24         g = t;
25     }
26     return sum;
27 }
28 // 二分,二分枚举一个答案mid,计算[1, mid]内有多少个数与m互质,让答案与K比较;
29 int Binary_search(int m, int K){
30     int l = 1, r = 2000000000, mid;
31     while(l <= r){
32         mid = (l + r) >> 1;
33         if(Count(mid, m) >= K) r = mid - 1;
34         else l = mid + 1;
35     }
36     return l;
37 }
38 int main()
39 {
40     int m, K;
41     while(scanf("%d%d", &m, &K) != EOF)
42     {
43         Div(m);
44         int ans = Binary_search(m, K);
45         printf("%d\n", ans);
46     }
47     return 0;
48 } 
时间: 2024-10-07 16:56:02

第k个互质数(二分 + 容斥)的相关文章

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

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

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 <

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

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

Codeforces 920G(二分+容斥)

题意: 定义F(x,p)表示的是一个数列{y},其中gcd(y,p)=1且y>x 给出x,p,k,求出F(x,p)的第k项 x,p,k<=10^6 分析: 很容易想到先二分,再做差 然后问题就变成了[1,x]内有多少个数是和p互质的 我们可以先将p质因数分解,然后用这些数组合去在[1,x]容斥就行了 1 long long cal(long long x) 2 { 3 int n=f.size(); 4 long long ans=0; 5 for(int i=0;i<(1<<

Codeforces 483B - Friends and Presents(二分+容斥)

483B - Friends and Presents 思路:这个博客写的不错:http://www.cnblogs.com/windysai/p/4058235.html 代码: #include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mem(a,b) memset((a),(b),sizeof(a)) const ll INF=1e18; ll c1,c2,

HAOI2018 [HAOI2018]染色 【组合数 + 容斥 + NTT】

题目 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度为 \(N\) 的序列, 每个位置都可以被染成 \(M\) 种颜色中的某一种. 然而小 C 只关心序列的 \(N\) 个位置中出现次数恰好为 \(S\) 的颜色种数, 如果恰 好出现了 \(S\) 次的颜色有 \(K\) 种, 则小 C 会产生 \(W_k\) 的愉悦度. 小 C 希望知道对于所有可能的染色方案, 他能获得的愉悦度的和对 1004535809 取模的结果是多少. 输入格式 从

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

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

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