BZOJ 2986: Non-Squarefree Numbers [容斥原理 二分]

题意:求第\(n \le 10^{10}\)个不是无平方因子数


二分答案,
容斥一下,0个质数的平方因子-1个.....
枚举\(\sqrt{mid}\)的平方因子乘上莫比乌斯函数,最后求出无平方因子数的个数取补集

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=3e5+5;
typedef long long ll;
inline ll read(){
	char c=getchar();ll x=0,f=1;
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return x*f;
}

ll k;
int notp[N], p[N], mu[N];
void sieve(int n) {
	mu[1] = 1;
	for(int i=2; i<=n; i++) {
		if(!notp[i]) p[++p[0]] = i, mu[i] = -1;
		for(int j=1; j<=p[0] && i*p[j]<=n; j++) {
			notp[i*p[j]] = 1;
			if(i%p[j] == 0) {mu[i*p[j]]=0; break;}
			mu[i*p[j]] = -mu[i];
		}
	}
}
bool check(ll n) { 
	ll m=sqrt(n), ans=0; //printf("hi %lld %lld\n",n,m);
	for(ll i=1; i<=m; i++) ans += mu[i]*(n/(i*i));
	ans = n-ans; //printf("check %lld %lld\n",n,ans);
	return ans>=k;
}
int main() {
	freopen("in","r",stdin);
	sieve(N-1);
	k=read();
	ll l=1, r=k<<2, ans=0;
	while(l<=r) {
		ll mid = (l+r)>>1;
		if(check(mid)) ans=mid, r=mid-1;
		else l=mid+1;
	}
	printf("%lld\n",ans);
}

posted @ 2017-03-24 17:21  Candy?  阅读(253)  评论(0编辑  收藏  举报