首页 > 代码库 > BZOJ 2440 [中山市选2011]完全平方数 ——莫比乌斯函数

BZOJ 2440 [中山市选2011]完全平方数 ——莫比乌斯函数

$\sum_{i=1}^n[i==d^2*p]$ 其中p无平方因子
$=\sum_{d^2\mid n,d>=2}\sum_{i=1}^{\lfloor {n/d^2} \rfloor} \left| \mu(i) \right |$
然后就成了计算$\left| \mu(i) \right |$ 的前缀和?
但是貌似不太可能啊 然后我们重新考虑容斥。
发现最终的结果 s=一个质数平方的倍数-两个质数乘积平方的倍数-三个的-五个的+6个的
发现系数和$\mu$一样,然后就可以枚举d进行计算了
$$\sum_{d^2<=n}\mu(d)*\lfloor {n/d^2} \rfloor$$
貌似就可以了

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (ll i=j;i<=k;++i)
#define D(i,j,k) for (ll i=j;i>=k;--i)
#define ll long long
#define maxn 100005
int vis[maxn],mu[maxn],pr[maxn],top=0;
void init()
{
    mu[1]=1;
    F(i,2,maxn-1)
    {
        if (!vis[i]) vis[i]=1,pr[++top]=i,mu[i]=-1;
        F(j,1,top)
        {
            if (i*pr[j]>=maxn) break;
            vis[i*pr[j]]=1;
            if (i%pr[j]==0){mu[i*pr[j]]=0;break;}
            mu[i*pr[j]]=-mu[i];
        }
    }
}
 
int t;ll k;
 
ll test(ll n)
{
    ll t=sqrt(n),ret=0;
    F(i,1,t) ret+=mu[i]*(n/(i*i));
    return ret;
}
 
int main()
{
    init();
    scanf("%d",&t);
    while (t--)
    {
        scanf("%lld",&k);
        ll l=0,r=30000000000LL;
        while (l<r)
        {
            ll mid=(l+r)>>1;
            if (test(mid)>=k) r=mid;
            else l=mid+1;
        }
        printf("%lld\n",r);
    }
}

  

 

BZOJ 2440 [中山市选2011]完全平方数 ——莫比乌斯函数