poj 2773 Happy 2006(容斥+二分)

来源:互联网 发布:linux播放avi屏幕闪烁 编辑:程序博客网 时间:2024/05/21 01:57

输入m和k,求与m互质的第k个数,与m互质的第一个数为1。先分析求某个范围内与m互质的数,肯定要容斥的,现在求第k个与m个互质的数字,而且范围不知道,既然不知道,那就二分来找这个范围,找到后也就找到结果了。

#include <stdio.h>#include <string.h>typedef __int64 LL;const LL One = 1;const LL INF = One<<61;LL p[62];int plen;void getFactor(LL num){    plen = 0;    for(LL i = 2; i <= num/i; ++i)    {        if(num%i == 0)        {            p[plen++] = i;            while(num%i == 0) num /= i;        }    }    if(num > 1) p[plen++] = num;}LL C(LL num){    LL res = 0;    LL limit = One<<plen;    for(LL i = 1; i < limit; ++i)    {        LL mult = 1;        LL cnt = 0;        for(int j = 0; j < plen; ++j)        {            if(i&(One<<j))            {                mult *= p[j];                cnt++;            }        }        if(cnt&1) res += num/mult;        else res -= num/mult;    }    return num-res;}int main(){    LL m,k;    while(scanf("%I64d %I64d",&m,&k) != EOF)    {        getFactor(m);        LL L = 1;        LL R = INF;        LL mid;        while(L <= R)        {            mid = (L+R) >> 1;            if(C(mid) < k)                L = mid + 1;            else                R = mid - 1;        }        printf("%I64d\n",L);    }    return 0;}
原创粉丝点击