bzoj2440: [中山市选2011]完全平方数 莫比乌斯容斥+二分

Description

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

Input

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

Output

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

K <= 1e9   

题解:首先二分,转换为计数问题。用莫比乌斯函数的特殊性质来容斥是很巧妙的套路!

                    而每个数都可以写成质数积,那么显然只要质数的平方的倍数就可以代替所有数的平方的倍数。

考虑质数个数,假设质数集PP,那么根据容斥原理,在[1,x][1,x]范围内的整数不能能分解的个数有:

x(Ap1+Ap2++Apk)+(Ap1p2+Ap1p3++Apk1pk)++(1)kAki=1pix−(Ap1+Ap2+⋯+Apk)+(Ap1⋅p2+Ap1⋅p3+⋯+Apk−1⋅pk)+⋯+(−1)kA∏i=1kpi

其中AS=xSSAS=⌊xS⋅S⌋,即[1,x][1,x]范围内S|TS|TTT个数。

而我们考虑莫比乌斯函数的定义,发现当μ(x)=(1)kμ(x)=(−1)k的定义恰好是指数均为1的定义!而符号又决定了容斥的符号!哈哈!

所以我们预处理mu后,因为根据每个数的最大平方因子为xx,那么我们只要枚举xx个数,然后用莫比乌斯来搞就行了!(from iwtwiioi)


然而为什么rank1速度是我的20倍


#include<bits/stdc++.h>
using namespace std;
#define maxn 100020

typedef long long ll;
int prime[maxn],tag[maxn],cnt,mu[maxn],tot,a[maxn];
int T,k;

void init(){
	mu[1] = 1;
	for (int i = 2 ; i <= 100000 ; i++){
		if ( !tag[i] ) prime[++cnt] = i , mu[i] = -1;
		for (register int j = 1 ; j <= cnt && i * prime[j] <= 100000 ; j++){
			tag[i * prime[j]] = 1;
			if ( (i % prime[j]) == 0 ){ mu[i * prime[j]] = 0; break; }
			mu[i * prime[j]] = -mu[i];
		}
	}
	for (register int i = 1 ; i <= 100000 ; i++) if ( mu[i] ) a[++tot] = i;
}
int check(ll x){
	ll cur = 0;
	for (register int i = 1 ; (ll)a[i] * a[i] <= x ; i++){
		cur += (x / a[i] / a[i]) * mu[a[i]];
	}
	return cur >= k;
}
int main(){
	scanf("%d",&T);
	init();
	while ( T-- ){
		scanf("%d",&k);
		ll l = 1 , r = k * 2ll,ans;
		while ( l <= r ){
			ll mid = (l + r) >> 1;
			if ( check(mid) ) ans = mid , r = mid - 1;
			else l = mid + 1;
		}
		cout<<ans<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值