[cf920G][容斥原理+二分]

  • Post author:
  • Post category:其他


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


x

,


p

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


x

,


p

and


k

for


i

-th query (

1 ≤

x

,

p

,

k

≤ 10

6).







Output

Print


t

integers, where


i

-th integer is the answer to


i

-th query.


Examples
input

Copy

3
7 22 1
7 22 2
7 22 3

output

Copy

9
13
15

input

Copy

5
42 42 42
43 43 43
44 44 44
45 45 45
46 46 46

output

Copy

187
87
139
128
141
题意:求出与p互质并且>x的第k小数
题解:首先求出p所有的质因子,状压枚举出质因子相乘的情况,比如000001表示只有一个最小的质因子,则在1-y中有y/prime[1]个,再通过容斥即可求出与p不互质的个数,此时二分答案y即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define debug(x) cout<<#x<<" is "<<x<<endl;
 4 typedef long long ll;
 5 ll sol(ll x,vector<ll>&f){
 6     ll res=0;
 7     int n=(int)f.size();
 8     for(int i=1;i<(1<<n);i++)
 9     {
10         ll now=1,sgn=-1;
11         for(int j=0;j<n;j++)
12             if(i&(1<<j))now*=f[j],sgn*=-1;
13         res+=sgn*(x/now);
14     }
15     return x-res;
16 }
17 int main(){
18     int t;
19     scanf("%d",&t);
20     while(t--){
21         ll x,p,k;
22         scanf("%lld%lld%lld",&x,&p,&k);
23         vector<ll>g;
24         for(ll i=2;i*i<=p;i++){
25             if(p%i==0){
26                 g.push_back(i);
27                 while(p%i==0){
28                     p/=i;
29                 }
30             }
31         }
32         if(p>1)g.push_back(p);
33         ll r=1000000000000LL;
34         ll l=0;
35         k+=sol(x,g);
36         ll ans;
37         while(l<=r){
38             ll mid=(l+r)/2;
39             if(sol(mid,g)>=k){
40                 ans=mid;
41                 r=mid-1;
42             }
43             else{
44                 l=mid+1;
45             }
46         }
47         printf("%lld\n",ans);
48     }
49     return 0;
50 }


View Code

转载于:https://www.cnblogs.com/MekakuCityActor/p/10926041.html