ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些
数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而
这丝毫不影响他对其他数的热爱。 
这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一
个小X讨厌的数。他列出了所有小X不讨厌的数,然后选取了第 K个数送给了
小X。小X很开心地收下了。 
然而现在小 W 却记不起送给小X的是哪个数了。你能帮他一下吗?

Input

包含多组测试数据。文件第一行有一个整数 T,表示测试
数据的组数。 
第2 至第T+1 行每行有一个整数Ki,描述一组数据,含义如题目中所描述。 

Output

含T 行,分别对每组数据作出回答。第 i 行输出相应的
第Ki 个不是完全平方数的正整数倍的数。

二分答案,利用容斥原理计算小于x的完全平方数个数t

t=x-x/2^2-x/3^2-x/5^2+x/(2*3)^2-x/7^2+x/(2*5)^2-x/11^2-x/13^2...

 =x-sigma(floor(x/mu(i)*i^2)),i=2,3,4,5...

线性筛处理莫比乌斯函数在0~45000的值即可

#include<cstdio>
int ps[45005],mu[45005],isnp[45005]={1,1},p=0;
int calc(int x){
    int t=x;
    for(int i=2,j;(j=i*i)<=x;i++)t-=mu[i]*x/j;
    return t;
}
bool nt(int x){
    for(int i=2;i*i<=x;i++)if(x%(i*i)==0)return 0;
    return 1;
}
int main(){
    for(int i=2;i<45000;i++){
        if(!isnp[i])ps[p++]=i,mu[i]=1;
        for(int j=0;j<p&&i*ps[j]<45000;j++){
            isnp[i*ps[j]]=1;
            if(i%ps[j]==0){
                mu[i*ps[j]]=0;
                break;
            }else{
                mu[i*ps[j]]=-mu[i];
            }
        }
    }
    int T;
    scanf("%d",&T);
    while(T--){
        unsigned int x,l=1,r,m;
        scanf("%d",&x);
        r=x*2+5;
        while(l+1<r){
            m=l+r>>1;
            if(calc(m)>x)r=m-1;
            else l=m;
        }
        if(calc(l)<x)++l;
        while(calc(l-1)==x)--l;
        while(!nt(l)&&calc(l+1)==x)++l;
        printf("%d\n",l);
    }
    return 0;
}

 

posted on 2016-03-24 13:25  nul  阅读(255)  评论(0编辑  收藏  举报