1. 程式人生 > >Educational Codeforces Round 37 (Rated for Div. 2)G. List Of Integers 二分

Educational Codeforces Round 37 (Rated for Div. 2)G. List Of Integers 二分

ini set 二分答案 sig fin 鏈接 scanf using article

題目鏈接:G. List Of Integers

題意:給你x,p,k,問你比x大的於p互質的第k個數.

題解:我們二分答案,如何判斷呢,我們先的會算1~n於p互質的個數,不會的可以看這個,其他就很簡單了。

#include<bits/stdc++.h>
#include<set>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define
PI 3.14159265 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define eps 1e-7 typedef unsigned long long ull; const int mod=1e9+7; const int maxn=3e5+5; const int root=1e6+7; using namespace std; int t; ll x,pp,k,tmp; vector<ll> p; void init(int n) { p.clear();
for(ll i=2;i*i<=n;i++) { if(n%i==0) { p.pb(i); while(n%i==0)n/=i; } }if(n>1)p.pb(n); } ll slove(ll r) { ll ans=0; for(ll msk=1;msk<(1<<p.size());msk++) { ll multi=1,bits=0; for(ll i=0;i<p.size();i++) {
if(msk&(1<<i))++bits,multi*=p[i]; } ll cnt=r/multi; if(bits&1)ans+=cnt; else ans-=cnt; } return r-ans; } bool judge(ll m) { if(slove(m)-tmp>=k) { return true; } return false; } int main() { scanf("%d",&t); while(t--) { scanf("%lld %lld %lld",&x,&pp,&k); init(pp); ll l=x+1,r=1e12; ll ans; tmp=slove(x); while(l<=r) { ll m=(l+r)/2; if(judge(m))ans=m,r=m-1; else l=m+1; } printf("%lld\n",ans); } return 0; }

Educational Codeforces Round 37 (Rated for Div. 2)G. List Of Integers 二分