nyoj762~第k个互质数(容斥原理+二分)

来源:互联网 发布:mac系统怎么隐藏文件夹 编辑:程序博客网 时间:2024/05/18 00:25

第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 110 210 3
样例输出
137
上传者

TC_常红立

容斥原理,要求第k个与m互质的数,可以二分整个区间,求每个范围内与m互质的数的个数;

而如何求1~num范围内与m互质的数的个数ans,此时就要用到容斥定理,求出与m不互质的数的个数,用总数-不互质的数的个数,即为所求;

容斥定理:ans=总数m-包含一个质因子的数+包含两个质因子的数-包含三个质因子的数~包含所有质因子的数

#include<stdio.h>#include<iostream>#include<string.h>#include<vector>#define N 100005#define LL long long intusing namespace std;vector<int>a;int b[100];void div(int m){    for(int i=2;i*i<=m;i++)    {        if(m%i==0)            a.push_back(i);        while(m%i==0)            m/=i;    }    if(m>1)a.push_back(m);}int cont(int m)//容斥定理,求出二分范围内内有多少个与m互质的数{    int sum=m,g=0;    b[++g]=1;    for(int i=0;i<a.size();i++)    {        int t=g;        for(int j=1;j<=g;j++)        {            //奇数个因子时为负,偶数个为正,负负得正            b[++t]=-1*a[i]*b[j];            //sum为与m互质的总个数            sum+=m/b[t];        }        g=t;    }    return sum;}int mid_find(int m,int k){    int le=1,ri=1000000000,mid;    //二分查找缩小范围求出解    while(le<=ri)    {         mid=(le+ri)/2;        if(cont(mid)>=k)            ri=mid-1;        else            le=mid+1;    }    return le;}int main(){    int m,k;    while(~scanf("%d%d",&m,&k))    {        a.clear();        div(m);        printf("%d\n",mid_find(m,k));    }}

0 0
原创粉丝点击