Happy 2006 (POJ-2773)(容斥原理+二分)

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 all relatively prime to 2006.

Now your job is easy: for the given integer m, find the K-th element which is relatively prime to m when these elements are sorted in ascending order.

Input

The input contains multiple test cases. For each test case, it contains two integers m (1 <= m <= 1000000), K (1 <= K <= 100000000).

Output

Output the K-th element in a single line.

Sample Input

2006 1
2006 2
2006 3

Sample Output

1
3
5

題意:給你m和k,讓你求出從1開始的第k個與m互質的數。

思路:這道題的話,乍一看,可以想到用容斥原理來求,因爲容斥原理可以求出1~n中所有與m互質的個數,但是我們不好判斷第幾個與m互質的數是多少。所以我們用到了二分查找,來不斷更新數值。

AC代碼:

#include <stdio.h>
#include <string>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
typedef long long ll;
const int maxx=100010;
const int mod=10007;
const int inf=0x3f3f3f3f;
using namespace std;
ll p[maxx];
ll q[maxx];
ll m,K,k;
void getp(ll n)
{
    k=0;
    for(ll i=2; i*i<=n; i++)
    {
        if(n%i==0)
        {
            p[k++]=i;
            while(n%i==0)
                n/=i;
        }
    }
    if(n>1)
        p[k++]=n;
}
ll nop(ll n)
{
    ll sum=0,t=0;
    q[t++]=-1;
    for(ll i=0; i<k; i++)
    {
        ll x=t;
        for(ll j=0; j<x; j++)
        {
            q[t]=q[j]*p[i]*(-1);
            t++;
        }
    }
    for(ll i=1; i<t; i++)
        sum+=n/q[i];
    return sum;
}
int main()
{
    while(~scanf("%lld%lld",&m,&K))
    {
        getp(m);
        ll l=1,r=1e18;
        ll mid,ans;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if((mid-nop(mid))>=K)
            {
                r=mid-1;
            }
            else
                l=mid+1;
        }
        printf("%lld\n",l);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章