完全平方数

前言

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

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

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

证明

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

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

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

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

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

\[\begin{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] \]

带入性质一

\[\begin{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} \rfloor \\ \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\n",r);
	}
}
posted @ 2020-01-12 16:07  RiverSheep  阅读(466)  评论(0编辑  收藏  举报