首页 > 代码库 > POJ 2773 Happy 2006 (二分答案+容斥)

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 maxn = 100;
typedef long long LL;
int m,k,cnt;
int p[maxn];

void fen(int m)//对m因子分解
{
    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;
}

LL calu(LL n)//容斥计数
{
    LL sum=0;
    for(LL i=1;i<(1<<cnt);i++){
        LL mult=1,f=0;
        for(int j=0;j<cnt;j++){
            if(i&(1<<j)){
                f++;
                mult*=p[j];
            }
        }
        if(f&1) sum+=n/mult;
        else sum-=n/mult;
    }
    return n-sum;
}

int main()
{
    while(~scanf("%d%d",&m,&k)){
        LL l=0,r=((LL)1<<62);
        LL mid,ans=0;
        fen(m);
        while(l<=r){//二分答案
            mid=(l+r)/2;

            LL sum = calu(mid);
            if(sum>=k){
                r=mid-1;
                if(sum==k) ans=mid;
            }
            else  l=mid+1;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


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