Educational Codeforces Round 37 (Rated for Div. 2) G
G. List Of Integers
time limit per test
5 secondsmemory limit per test
256 megabytesinput
standard inputoutput
standard outputLet'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 ≤ 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); } }