第k个互质数
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
- 描述
-
两个数的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
-
#include<iostream> #include<vector> using namespace std; vector<int> yinzi; int m,k; void fetch(int mm) { for(int i=2;i*i<=m;i++) { if(mm%i==0) { yinzi.push_back(i); while(mm%i==0) mm/=i; } } if(mm>1)//如果自己是质数那么把自己添加 yinzi.push_back(mm); } int cnt(int top) { int sum=top; int t[1000]; int g=0; t[g++]=1;//奇数个或者偶数个因子数目 for(int i=0;i<yinzi.size();i++) { int tt=g; for(int j=0;j<g;j++) { t[tt++]=(-1*yinzi[i]*t[j]);//偶数个质因子为正,奇数个质因子为负 sum+=top/t[tt-1];//计算[1,n]之间有多少数含有因子b[t] } g=tt; } return sum; } //二分枚举答案mid,计算[1,mid]内有多少个数与m互质,并将其结果与k比较 int Binary_search()//相当于一个二分查找,找到这个mid,如果1到mid区间内的与m的互质数大于或者等于k那么区间下移来逼近第k个,如果1到mid区间内的与m的互质数小于k说明区间小了,那么区间上移来逼近第k个互质数 { int le=0; long long ri=1000000000;//因为是10位了,于是我就定义一个long long while(le<=ri) { int mid=(le+ri)/2; if(cnt(mid)>=k) { ri=mid-1; } else le=mid+1; } return le;//由于mid的每次计算都是下取整的所以返回le } int main() { while(cin>>m>>k) { yinzi.clear(); fetch(m); cout<<Binary_search()<<endl; } }