$\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); } }
时间: 2024-10-27 16:34:00