码迷,mamicode.com
首页 > 其他好文 > 详细

[CF920G]List Of Integers

时间:2019-02-13 22:33:05      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:推出   eve   const   bre   pre   要求   lis   using   lse   

Description:

\(t\)组询问,求第\(k\)个大于\(x\)且与\(p\)互质的数

Hint:

\(x,k,p<=1e6,t<=30000\)

Solution:

推出式子后,由于要求第k大,二分答案就好了

#include<bits/stdc++.h>
using namespace std;
const int mxn=1e6+5;
int tot,vis[mxn],mu[mxn],sum[mxn],p[mxn];

void sieve(int lim) 
{
    mu[1]=1;
    for(int i=2;i<=lim;++i) {
        if(!vis[i]) mu[i]=-1,p[++tot]=i;
        for(int j=1;j<=tot&&p[j]*i<=lim;++j) {
            vis[p[j]*i]=1;
            if(i%p[j]==0) {
                mu[p[j]*i]=0;
                break;
            }
            mu[p[j]*i]=-mu[i];
        }
    }
    for(int i=1;i<=lim;++i) sum[i]=sum[i-1]+mu[i];
}

int check(int x,int p)
{
    int ans=0;
    for(int i=1;i<=sqrt(p);++i) 
        if(p%i==0) {
            ans+=mu[i]*(x/i);
            if(i*i!=p) ans+=mu[p/i]*(x/(p/i)); //这里很重要,直接将O(n)的check优化到了O(√n)
        }
        
    return ans; 
}

int main()
{
    int t,x,p,k;
    scanf("%d",&t); sieve(1000000);
    while(t--) {
        scanf("%d%d%d",&x,&p,&k);
        int l=x+k-1,r=9e6+5;
        while(l<r) {
            int mid=(l+r)>>1;
            if(check(mid,p)-check(x,p)>=k) r=mid;
            else l=mid+1;
        }
        printf("%d\n",r);
    }
    return 0;
}

[CF920G]List Of Integers

标签:推出   eve   const   bre   pre   要求   lis   using   lse   

原文地址:https://www.cnblogs.com/list1/p/10372063.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!