List Of Integers

List Of Integers

https://ac.nowcoder.com/acm/problem/112558

题意:询问[x,p,k],找出比x大且与p互质的第k个数


解题思路:
idea很简单
首先容斥原理可以算出某个范围内的与x互质的个数(oi-wiki上有介绍)
二分范围

dfs比二进制快一点
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long LL;
template <class T>
void read(T &val) { T x = 0; T bz = 1; char c; for (c = getchar(); (c<'0' || c>'9') && c != '-'; c = getchar()); if (c == '-') { bz = -1; c = getchar(); }for (; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - 48; val = x * bz; }
const int mod=1e9+7;
const int maxn = 1e6+10;
int cnt = 0;
int b[maxn];
void divide(int p){
    cnt=0;
    for(int i=2;i*i<=p;i++){
        if(p%i==0){
            b[++cnt]=i;
            while(p%i==0) p/=i;
        }
    }
    if(p>1) b[++cnt]=p;
}

LL num = 0;
void dfs(LL x,int dep,int times){
    if(dep>cnt){
        if(times&1) num-=x;
        else num+=x;
        return;
    }
    dfs(x,dep+1,times);
    dfs(x/b[dep],dep+1,times+1);
}

LL cal(LL x){
    num = 0;
    dfs(x,1,0);
    return num;
}

int main(){
    int t;read(t);
    while(t--){
        LL x,p,k,l,r,ans=0;
        read(x);read(p);read(k);
        divide(p);
        k+=cal(x);
        l = x+1;r = 1e9;
        while(l<=r){
            LL mid=l+r>>1;
            if(cal(mid)>=k){
                ans=mid;r=mid-1;
            }
            else l=mid+1;
        }
        printf("%lld\n",ans);
    }
    return 0;
}



全部评论

相关推荐

3 收藏 评论
分享
牛客网
牛客企业服务