完全平方数 HYSBZ - 2440【莫比乌斯函数+二分】
作者:互联网
题意:
求出第 \(ki\) 个不是完全平方数的整数倍的数。(\(1\) 是第一个)
数据范围:\(1 ≤ Ki ≤ 10^9,T ≤ 50\)
分析:
首先可以想到,用容斥定理来求。但实际上,完全平方数有很多,不可能一个一个地枚举出来,然后奇加偶减。
对于 \(\sqrt{n}\) 以内的素数集合:\(s\),\(n\) 以内的不含完全平方数因子的数的个数:
\(ans=\frac{n}{1*1}-\frac{n}{2*2}-\frac{n}{3*3}-\frac{n}{5*5}+\frac{n}{6*6}...\)
显然,偶数个质数平方对于答案的贡献就是正的,否则是负;如果不是若干个互异质数的乘积,那么对答案没有影响,因为它们已经被所含的质数处理过。
所以:
\[ans=\sum_{i=1}^{\sqrt{n}}{mu[i]*\frac{n}{i*i}}\]
结合二分即可找出符合条件的数。
注意:
1.二分时,是找到第一个满足条件的数,所以在改变区间时要注意写法;
2.二分时,\(l+r\) 会爆 \(int\) 。
代码:
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int N=1e5+5;
int mu[N];
vector<int>prime;
bool vis[N];
void read(int &x)
{
x=0;
int f=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
x*=f;
}
void init()
{
mu[1]=1;
memset(vis,0,sizeof(vis));
for(int i=2;i<=N-5;i++)
{
if(!vis[i])
{
prime.pb(i);
mu[i]=-1;
}
for(int j=0;j<prime.size()&&1LL*prime[j]*i<=N-5;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else
mu[i*prime[j]]=-mu[i];
}
}
}
ll solve(int n)
{
ll ans=0;
for(int i=1;1LL*i*i<=n;i++)
ans+=(mu[i]*n/(i*i));
return ans;
}
int main()
{
int t,k;
init();
read(t);
while(t--)
{
read(k);
ll l=1,r=2*k+5;
while(l<=r)
{
ll mid=(l+r)>>1;
ll t=solve(mid);
if(t<k)
l=mid+1;
else
r=mid-1;
}
printf("%lld\n",l);
}
return 0;
}
标签:二分,2440,ch,frac,int,HYSBZ,质数,平方,莫比 来源: https://www.cnblogs.com/1024-xzx/p/12537070.html