zoukankan      html  css  js  c++  java
  • [BZOJ 2440][中山市选2011]完全平方数

    Description

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

    Input

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

    Output

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

    Sample Input

    4
    1
    13
    100
    1234567

    Sample Output

    1
    19
    163
    2030745

    HINT

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

    题解

    既然要求没有平方因子,等价于这个数唯一分解后素因数次数均为 1 。显然就是求 $mu eq 0$ 的第 $K$ 个值。

    然而 $Kleq 10^9$ 是存不下的。我们换一个思路。

    我们试着枚举每个不含平方因子的数 $i$ 用容斥原理筛出。值得注意的是有贼有意思的事情:由莫比乌斯函数的定义,我们可以确定在 $N$ 内的满足题意的数的个数为 $$ans=N+sum_{i=2}^{sqrt N}mu(i)leftlfloorfrac{N}{i^2} ight floor$$

    所以二分答案,再 $O(sqrt N)$ 检验即可。

     1 //It is made by Awson on 2018.1.23
     2 #include <set>
     3 #include <map>
     4 #include <cmath>
     5 #include <ctime>
     6 #include <queue>
     7 #include <stack>
     8 #include <cstdio>
     9 #include <string>
    10 #include <vector>
    11 #include <cstdlib>
    12 #include <cstring>
    13 #include <iostream>
    14 #include <algorithm>
    15 #define LL long long
    16 #define Abs(a) ((a) < 0 ? (-(a)) : (a))
    17 #define Max(a, b) ((a) > (b) ? (a) : (b))
    18 #define Min(a, b) ((a) < (b) ? (a) : (b))
    19 #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
    20 #define writeln(x) (write(x), putchar('
    '))
    21 #define lowbit(x) ((x)&(-(x)))
    22 using namespace std;
    23 const int K = 1e9;
    24 const int N = 1e5;
    25 void read(int &x) {
    26     char ch; bool flag = 0;
    27     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
    28     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
    29     x *= 1-2*flag;
    30 }
    31 void write(LL x) {
    32     if (x > 9) write(x/10);
    33     putchar(x%10+48);
    34 }
    35 
    36 int n, m, mu[N+5];
    37 int isprime[N+5], prime[N+5], tot;
    38 
    39 void get_mu() {
    40     memset(isprime, 1, sizeof(isprime)); isprime[1] = 0, mu[1] = 1;
    41     for (int i = 2; i <= N; i++) {
    42     if (isprime[i]) prime[++tot] = i, mu[i] = -1;
    43     for (int j = 1; j <= tot && i*prime[j] <= N; j++) {
    44         isprime[i*prime[j]] = 0;
    45         if (i%prime[j]) mu[i*prime[j]] = -mu[i];
    46         else {mu[i*prime[j]] = 0; break; }
    47     }
    48     }
    49 }
    50 int cal(int m, int k) {
    51     int n = sqrt(m); LL ans = m;
    52     for (int i = 2; i <= n; i++) ans += (LL)mu[i]*(m/i/i);
    53     return ans >= k;
    54 }
    55 void work() {
    56     read(n); int L = 1, R = n<<1, ans = n;
    57     while (L <= R) {
    58     int mid = ((LL)L+R)>>1;
    59     if (cal(mid, n)) ans = mid, R = mid-1;
    60     else L = mid+1;
    61     }
    62     writeln(ans);
    63 }
    64 int main() {
    65     int t; read(t); get_mu();
    66     while (t--) work();
    67     return 0;
    68 }
  • 相关阅读:
    [C++]猜词游戏简版
    [C++]异常处理实例-基础版
    C++Primer Plus习题记录-Chapter12
    C++Primer Plus习题记录-Chapter11
    [C++]MI(多继承)实例-基础版
    Windows下编译libevent及使用
    jquery点击回到顶部
    简体繁体转换
    检测ip和地区
    点击复制到剪切板
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8337418.html
Copyright © 2011-2022 走看看