HYSBZ - 2440 完全平方数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fadedsun/article/details/82828209

很菜,这道题看了很多博客. 后天就出去比赛了.恍然就没时间了.

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

史上最全解题记录来啦!

我承认题解越详细,代表我越菜.emmmmm
开始学莫比乌斯反演,然后看了popoqqq的PPT,突然觉得这个东东也没那么难嘛
emmmmmmmm,我为我的浅薄无知,道歉.

因为题目范围是1e9 ,所以预处理答案存不下来.
意味着不能把所有合法数据打出来

用二分吧,
那么问题就变成判定{1,x} 有多少个合法数字.

可以思考得出,题目中合法的数字就是"无平方因子数"
也就是说这个数唯一分解以后,所有质因子个数均为 1 .

然后就用到容斥了,话说,容斥理解起来简单,但用起来
好吧,想不到是真的
引用popoqqq
X以内的无平方因子数=
0个质数乘积平方的倍数的数的数量-1个质数乘积平方的倍数的数的数量+
2个质数乘积平方的倍数的数的数量…

这个数是由几个质数乘起来的 , 怎么去判定,嗯,
这个问题其实是由莫比乌斯函数解决
枚举1到 x ,如果这个数有平方因子,可以知道莫比乌斯函数值为0
其他的就可以通过莫比乌斯函数值的正负判断质数的奇偶

还有一个小问题,对于 i ,在 x 以内,ii 的倍数有多少个呢?
答案是:x/(i
i) , 为什么呢? 用10除2,除3试试看,就知道了
为什么枚举到i*i <= x就可以了呢,
因为i再大的话,就超过x了啊
我还纠结了1分钟,哇饿哇哇哇额

注意:

二分的时候注意溢出(l+r)/2 会出问题

# include <cstdio>
# include <cstring>

using namespace std;

const int N = 1e5+10;
int vis[N],mu[N],prime[N],cnt;

void init()
{
	memset(vis,0,sizeof(vis));
	mu[1] = 1;
	cnt = 0;
	for(int i = 2;i < N;i++)
	{
		if(!vis[i]){
			prime[cnt++] = i; mu[i] = -1;
		}
		for(int j = 0;j < cnt && i*prime[j] < N;j++){
			vis[prime[j]*i] = 1;
			if(i%prime[j]) mu[i*prime[j]] = -mu[i];
			else{
				mu[i*prime[j]] = 0;break;
			}
		}
	}
}

int check(int x,int k){
	int r = 0;
	for(int i = 1;i*i <= x;i++){
		r += x/i/i * mu[i];
	}
	return r >= k;
}
int main()
{
	init();
	int T,k;
	
	scanf("%d",&T);
	
	while(T--)
	{
		scanf("%d",&k);
		
		int l = 1,r = 2*k,mid,ans;
		while(l <= r)
		{
			mid = (r - l) / 2 + l;
			if(check(mid,k)){
				r = mid-1;
				ans = mid;
			}else{
				l = mid+1;
			}
		}
		printf("%d\n",ans);
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/fadedsun/article/details/82828209