bzoj2440,luoguP4318 完全平方数

传送门:完全平方数

无平方因子数(square free number,sfn) :唯一分解后每个质数的幂次都为1。

二分答案,问题变为统计$ \leq n $的数字中有多少个无平方因子数。

首先删掉4及4的倍数,再删掉9及9的倍数,再删掉25及25的倍数,再加回来36及36的倍数...

容易发现是容斥,容斥系数是莫比乌斯函数

即小于等于\(n\)\(sfn\)个数为\(\sum_d^{\sqrt{n}}\lfloor\frac{n}{d^2}\rfloor\mu(d)\),显然可以根号计算

#define B cout << "BreakPoint" << endl;
#define O(x) cout << #x << " " << x << endl;
#define O_(x) cout << #x << " " << x << " ";
#define Msz(x) cout << "Sizeof " << #x << " " << sizeof(x)/1024/1024 << " MB" << endl;
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#define LL long long
const int inf = 1e9 + 9;
const int N = 2e5 + 5;
using namespace std;
inline int read() {
	int s = 0,w = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9') {
		if(ch == '-')
			w = -1;
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9') {
		s = s * 10 + ch - '0';
		ch = getchar();
	}
	return s * w;
}
const int M=1e5+5;
int mu[M],pn[M];
bool vis[M];
LL check(LL n) {
    LL num=0;
    for(LL i=1;i*i<=n;++i) {
        num+=mu[i]*(n/(i*i));
    }
    return num;
}
void init(){
	mu[1] = 1; 
	int cnt = 0;
    for(int i = 2;i <= 1e5;++i) {
        if(!vis[i]) mu[i] = -1,pn[++cnt] = i;
        for(int j = 1;j <= cnt && i * pn[j] <= 1e5;++j) {
            vis[i * pn[j]] = 1;
            if(i % pn[j] == 0) break;
            mu[i * pn[j]] = -mu[i];
        }
    }
    return ;
}
void solve(){
	LL k = read();
    LL l = 1,r =(k << 1);
    while(l < r) {
        LL mid = (l + r) >> 1;
        if(check(mid) >= k) r = mid;
        else l = mid + 1;
    }
    printf("%lld\n",l);
    return ;
}
int main() {
    init();
    int T = read();
    while(T--) {
        solve();
    }
    return 0;
}
posted @ 2020-03-15 21:53  优秀的渣渣禹  阅读(134)  评论(0编辑  收藏  举报