Educational Codeforces Round 37 (Rated for Div. 2) G

G. List Of Integers
time limit per test
5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Let's denote as L(x, p) an infinite sequence of integers y such that gcd(p, y) = 1 and y > x (where gcd is the greatest common divisor of two integer numbers), sorted in ascending order. The elements of L(x, p) are 1-indexed; for example, 9, 13 and 15 are the first, the second and the third elements of L(7, 22), respectively.

You have to process t queries. Each query is denoted by three integers xp and k, and the answer to this query is k-th element of L(x, p).

Input

The first line contains one integer t (1 ≤ t ≤ 30000) — the number of queries to process.

Then t lines follow. i-th line contains three integers xp and k for i-th query (1 ≤ x, p, k ≤ 106).

Output

Print t integers, where i-th integer is the answer to i-th query.

Examples
input
3
7 22 1
7 22 2
7 22 3
output
9
13
15
input
5
42 42 42
43 43 43
44 44 44
45 45 45
46 46 46
output
187
87
139
128
141

题意 q个询问 大于x,第k个与p互质的数
解析 对于一个数 mid 我们可以容斥算出1-mid 与 p互质的数有多少,所以二分答案就可以了。
AC代码
#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define huan printf("\n")
#define debug(a,b) cout<<a<<" "<<b<<" "<<endl
#define ffread(a) fastIO::read(a)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=1e4+10;
const ll mod=1000000007;
ll yinzi[maxn],cnt;
void euler(ll n)
{
    cnt=0;
    ll a=n;
    for(ll i=2; i*i<=a; i++)
    {
        if(a%i==0)
        {
            yinzi[cnt++]=i;
            while(a%i==0)
                a/=i;
        }
    }
    if(a>1)
        yinzi[cnt++]=a;
}
ll solve(ll n)
{
    ll ans=0;
    for(ll i=0; i<(1<<cnt); i++)
    {
        ll temp=1,jishu=0;
        for(ll j=0; j<cnt; j++)
        {
            if(i&(1<<j))
                temp=temp*yinzi[j],jishu++;
        }
        if(jishu==0)
            continue;
        if(jishu&1)
            ans+=n/temp;
        else
            ans-=n/temp;
    }
    return ans;
}
int main()
{
    ll t,n,m,k;
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld%lld",&m,&n,&k);
        euler(n);
        ll ans1=m-solve(m);
        ll l=m+1,r=1e7;
        while(l<=r)
        {
            ll mid=(l+r)/2;
            ll cur=mid-solve(mid)-ans1;
            if(cur<k)
                l=mid+1;
            else
                r=mid-1;
        }
        printf("%lld\n",r+1);
    }
}

猜你喜欢

转载自www.cnblogs.com/stranger-/p/9811509.html