• BZOJ2440 [中山市选2011]完全平方数


    Description

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

    Input

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

    Output

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

    Sample Input



    13 
    100 
    1234567

    Sample Output


    19 
    163 
    2030745

    HINT

    对于 100%的数据有 1 ≤ Ki ≤ 10^9, T ≤ 50


    考虑二分答案,然后判断是否有那么多数,然后根据莫比乌斯函数的性质完成容斥。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<cstring>
     8 using namespace std;
     9 #define maxn 200010
    10 #define N 200000
    11 #define llg long long
    12 #define inf (llg)1e12
    13 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    14 llg n,m,val,mobius[maxn],prime[maxn],cnt,bj[maxn],T;
    15 llg l,r,mid,ans;
    16 
    17 void init()
    18 {
    19     mobius[1]=1;
    20     for (llg i=2;i<=N;i++)
    21     {
    22         if (!bj[i]) prime[++cnt]=i,mobius[i]=-1;
    23         for (llg j=1;j<=cnt && prime[j]*i<=N;j++)
    24         {
    25             bj[i*prime[j]]=1;
    26             if (i%prime[j]) mobius[i*prime[j]]=-mobius[i];
    27             else
    28             {
    29                 mobius[i*prime[j]]=0;
    30                 break;
    31             }
    32         }
    33     }
    34 }
    35 
    36 bool check(llg x)
    37 {
    38     llg up=sqrt(x+0.5),tot=0;
    39     for (llg i=1;i<=up;i++)
    40     {
    41         tot+=mobius[i]*(x/(i*i));
    42     }
    43     if (tot>=val) return 1;
    44     else return 0; 
    45 }
    46 
    47 int main()
    48 {
    49     yyj("a");
    50     init();
    51     cin>>T;
    52     while (T--)
    53     {
    54         cin>>val;
    55         l=1,r=inf;
    56         while (l<=r)
    57         {
    58             mid=(l+r)>>1;
    59             if (check(mid)) ans=mid,r=mid-1;else l=mid+1;
    60         }
    61         printf("%lld
    ",ans);
    62     }
    63 
    64     return 0;
    65 }

    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    学习SpringMVC——从HelloWorld开始
    线性队列
    线性表之链表
    线性表之顺序表
    nextSibling 属性与 nextElementSibling 属性的异同
    JavaScript数组增删方法总结
    class关键字
    JS三座大山_单线程&EventLoop
    JS三座大山_闭包
    JS三座大山_原型与原型链
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6363679.html
Copyright © 2020-2023  润新知