[cf920G][容斥原理+二分]
Posted mekakucityactor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[cf920G][容斥原理+二分]相关的知识,希望对你有一定的参考价值。
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).
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 ≤ 106).
Print t integers, where i-th integer is the answer to i-th query.
3
7 22 1
7 22 2
7 22 3
9
13
15
5
42 42 42
43 43 43
44 44 44
45 45 45
46 46 46
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 }
以上是关于[cf920G][容斥原理+二分]的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 920G - List Of Integers
POJ 2773 Happy 2006#素数筛选+容斥原理+二分