完全平方数

前言

刚刚学习了莫比乌斯函数和性质一:
性质一:

[sum_{d|n} mu(d) = [n=1] ]

([n=1])表示(n=1)返回(1),否则返回(0)

证明

(n>1)
(omega(n))表示(n)的不同质因子的个数

[egin{aligned} sum_{d|n} mu(d) &= sum_{i=0}^{omega(n)} inom{omega(n)}{i} (-1)^i \ &=sum_{i=0}^{omega(n)} inom{omega(n)}{i} (-1)^i * 1^{omega(n)-i} \ end{aligned} ]

看到这个就会想到二次式定理:

[(a+b)^n = sum_{i=0}^n inom{n}{i} a^i b^{n-i} ]

根据二次式定理
可以继续化简

[egin{aligned} &=(-1+1)^{omega(n)} \ &=0 \ end{aligned} ]

(n=1)
不用说(mu(1)=1)
证毕

进入正题

题目大意:(N)组数据,求第(k)大的不是完全平方数的倍数的数
(x)为不是完全平方数的倍数的数
(mu ^2 (x)=1)

[f(i)=max_{d^2|i} d ]

那么当(f(i)=1)时,(i)就为不是完全平方数的倍数的数
则从(1)(n)的不是完全平方数的倍数的数的个数为

[sum_{i=1}^n [f(i)=1] ]

带入性质一

[egin{aligned} &= sum_{i=1}^n sum_{d|f(i)} mu(d) \ &= sum_{i=1}^n sum_{d^2|i} mu(d) \ &= sum_{d=1} sum_{d^2|i} mu(d) \ &= sum_{d=1} mu(d) sum_{d^2|i} 1 \ &= sum_{d=1} mu(d) lfloor frac{n}{d^2} floor \ end{aligned} ]

结束
(mu)的值可以用筛法求出
时间复杂度为(O(sqrt n log n))

代码:

#include<cstdio>
#define ll long long
using namespace std;
int mo[400000],p[400000],tot=0,n;
bool vis[400000];

void init()
{
	mo[1]=1;
	for (int i=2;i<=320000;i++)
	{
		if (!vis[i]) p[++tot]=i,mo[i]=-1;
		for (int j=1;j<=tot&&p[j]*i<=320000;j++)
		{
			vis[p[j]*i]=true;
			if (i%p[j]==0) break;
			mo[p[j]*i]=-mo[i];
		}
	}
}
bool check(ll x)
{
	ll res=0;
	for (int i=1;i*i<=x;i++)
		res+=mo[i]*(x/(i*i));
	return res>=n;
}
int main()
{
	init();
	int t;
	scanf("%d",&t);
	while (t--)
	{
		scanf("%d",&n);
		ll l=n,r=n<<1;
		while (l<r)
		{
			ll mid=(l+r)>>1;
			if (check(mid)) r=mid;
			else l=mid+1;
		}
		printf("%lld
",r);
	}
}
原文地址:https://www.cnblogs.com/nibabadeboke/p/12182919.html