BZOJ 2440 完全平方数(莫比乌斯反演+二分查找)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=23362

题意:定义含有平方数因子的数为完全平方数(平方数因子不包含1)。求第k个非完全平方数。

思路:我们先求出[1, n]的非完全平方数的个数,然后利用二分来查找正好等于k时的n(注意这样的n可能不止一个,求最左边的)。关键是,怎么求出前者,我们可以利用容斥原理,用n - [1, n]内完全平方数的个数,求[1, n]内完全平方数的个数,用容斥发现前面的系数就是莫比乌斯函数,直接用莫比乌斯反演即可,结果为sigma(mu[i]*(n/(i*i)))。

code:

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4
 5 typedef long long LL;
 6
 7 const LL INF = 2e10 + 7;
 8 const int MAXN = 100005;
 9
10 bool check[MAXN];
11 int primes[MAXN];
12 int mu[MAXN];
13 LL k;
14
15 void moblus()
16 {
17     memset(check, false, sizeof(check));
18     mu[1] = 1;
19     int cnt = 0;
20     for (int i = 2; i < MAXN; ++i) {
21         if (!check[i]) {
22             primes[cnt++] = i;
23             mu[i] = -1;
24         }
25         for (int j = 0; j < cnt; ++j) {
26             if (i * primes[j] > MAXN) break;
27             check[i * primes[j]] = true;
28             if (i % primes[j] == 0) {
29                 mu[i * primes[j]] = 0;
30                 break;
31             } else {
32                 mu[i * primes[j]] = -mu[i];
33             }
34         }
35     }
36 }
37
38 LL cal(LL n)
39 {
40     LL ret = n;
41     for (LL i = 2; i * i <= n; ++i) {
42         ret += mu[i] * (n / (i * i));
43     }
44     return ret;
45 }
46
47 int main()
48 {
49     moblus();
50     int nCase;
51     scanf("%d", &nCase);
52     while (nCase--) {
53         scanf("%lld", &k);
54         LL lhs = 1L;
55         LL rhs = INF;
56         LL mid;
57         while (lhs < rhs) {
58             mid = (rhs + lhs) / 2;
59             LL tmp = cal(mid);
60             if (tmp < k) lhs = mid + 1;
61             else rhs = mid;
62         }
63         printf("%lld\n", lhs);
64     }
65     return 0;
66 }
时间: 2024-10-28 16:23:32

BZOJ 2440 完全平方数(莫比乌斯反演+二分查找)的相关文章

BZOJ 2440 完全平方数(莫比乌斯反演,容斥原理)

http://www.lydsy.com/JudgeOnline/problem.php?id=2440 题意:求第K个没有平方因子的数 思路:首先,可以二分数字,然后问题就转变成x以内有多少无平方因子的数 根据容斥原理:x以内无平方因子数=1*无需是任何质数的倍数的数数量-1*至少是1个质数的平方的倍数的数数量+1*至少是2个质数的平方的倍数的数量-1*至少是3个质数的平方的倍数的数量............然后发现,莫比乌斯函数u[i]正好满足:当i是不同的质数乘积时,返回-1,有相同因子就

bzoj 2440 简单莫比乌斯反演

题目大意: 找第k个非平方数,平方数定义为一个数存在一个因子可以用某个数的平方来表示 这里首先需要考虑到二分才可以接下来做 二分去查找[1 , x]区间内非平方数的个数,后面就是简单的莫比乌斯反演了 容斥原理的思想,首先考虑所有数都属于非平方数 那么就是x 然后对于每一个平方数都要减去,但是这里应该只考虑质数的平方数就可以了 那么就扩展为x - x/(2^2) - x/(3^2) - x/(k^2).... 然后因为中间存在重复减的那么要加回来 -> x - x/(2^2) - x/(3^3) 

HYSBZ 2440 完全平方数(莫比乌斯反演)

若i为质数,n为i*i的倍数,则称n为含平方因子数. 求1~n的无平方因子数. F(x)为1~x的平方因子数数量,则由容斥原理及莫比乌斯函数知: G(x)为1~x的无平方因子数数量,则: 二分法枚举,注意二分法的写法. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<queue> #include<vector> #inc

bzoj [SDOI2014]数表 莫比乌斯反演 BIT

bzoj [SDOI2014]数表 莫比乌斯反演 BIT 链接 bzoj luogu loj 思路 \[ \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}a*[f[gcd(i,j)]<=a] \] \[ f[]可以O(n)预处理出来 \] \[ \sum\limits_{k=1}^{n}f[k]*\sum\limits_{i=1}^{m}\sum\limits_{j=1}^{m}[gcd(i,j)==k] \] \[ \sum\limits_{k=1}^{n}

BZOJ 2818 Gcd (莫比乌斯反演 或 欧拉函数)

2818: Gcd Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 2534  Solved: 1129 [Submit][Status][Discuss] Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的 数对(x,y)有多少对. Input 一个整数N Output 如题 Sample Input 4 Sample Output 4 HINT hint 对于样例(2,2),(2,4),(3,3),(4,2)

bzoj 1101 Zap —— 莫比乌斯反演

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1101 直接莫比乌斯反演. 代码如下: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int const xn=5e5+5; int pri[xn],cnt,mu[xn]; bool vis[xn]; int rd()

BZOJ 2440 完全平方数 (容斥+莫比乌斯反演+二分)

2440: [中山市选2011]完全平方数 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1673  Solved: 799 [Submit][Status][Discuss] Description 小 X 自幼就很喜欢数.但奇怪的是,他十分讨厌完全平方数.他觉得这些 数看起来很令人难受.由此,他也讨厌所有是完全平方数的正整数倍的数.然而 这丝毫不影响他对其他数的热爱. 这天是小X的生日,小 W 想送一个数给他作为生日礼物.当然他不能送一 个

BZOJ 2440 中山市选 2011 完全平方数 莫比乌斯函数+二分

题目大意 给出一个数k,求第k个不是完全平方数个数的数字(这里的完全平方数并不包括1). 思路 首先介绍一下莫比乌斯函数(M?bius): μ(x)=? ? ? ? ? ? ?  1(?1) k 0 x=1能分解成k个不同的质因数的乘积其他情况 然后呢,由于莫比乌斯函数是个积性函数,于是我们就可以线性地求出所有需要的莫比乌斯函数值. 剩下的工作就是在外层套一个二分,转成判定问题,小于一个数的数字中有多少个数字不是完全平方数的倍数.这个东西用容斥乱搞一下就好了~ CODE #define _CRT

BZOJ 2440 完全平方数

考虑二分答案.而且1..n中他喜欢的大概占3/5左右. 考虑莫比乌斯函数与容斥原理,得答案. #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #define maxn 100050 using namespace std; long long t,n,miu[maxn],prime[maxn],cnt=0; bool vis[maxn]; void get_table