【bzoj2440】完全平方数

mac2022-06-30  11

题意:

求第n个不为完全平方数倍数的数

题解:

网上有人说答案不会超过2n (求证0 0?) 竟然不超过2n 那么很明显就是用二分做了

二分判定就是要求小于等于n的合法的数的个数

不难发现一个数若为完全平方数的倍数 则他的质因子肯定有一个的指数大于1

那么合法的数的所有质因数质数肯定都为1

_________________________________________________________________________________

于是题目变为 求小于等于的质因数指数都为1的数的个数

我们可以把<=n的 所有i^2的倍数的数减掉(i为质数)

算重?

莫比乌斯函数!(容斥原理- -)

答案就是n-奇数个质数的平方的倍数的个数+偶数个质数的平方的倍数的个数

即 ans=Σmiu[i]*(n/i^2)  (i<=(int) sqrt(n) 显然i如果>sqrt(n)个数肯定为0)

            1    (i为奇数个质数的乘积)

miu[i]=  -1  (i为偶数个质数的乘积)

            0    (i有某个质数指数>1)

_________________________________________________________________________________

代码:

1 #include <cstdio> 2 #include <cmath> 3 typedef long long ll; 4 const ll M=100001; 5 ll t,n,miu[M],pri[M],bo[M],ans; 6 void makemiu(){ 7 miu[1]=1; 8 for (ll i=2;i<M;i++){ 9 if (!bo[i]){ 10 pri[++pri[0]]=i; 11 miu[i]=-1; 12 } 13 for (ll j=1;j<=pri[0] && pri[j]*i<M;j++){ 14 bo[i*pri[j]]=1; 15 if (i%pri[j]==0){ 16 miu[i*pri[j]]=0; 17 break; 18 }else miu[i*pri[j]]=-miu[i]; 19 } 20 } 21 } 22 ll check(ll t){ 23 ll sq=(int)sqrt(t),res=0; 24 for (ll i=1;i<=sq;i++) 25 res=res+miu[i]*(t/(i*i)); 26 return res; 27 } 28 ll getans(ll t){ 29 ll l=0,r=t*2,mid; 30 while (l+1<r){ 31 mid=(l+r)/2; 32 if (check(mid)<t) l=mid; 33 else r=mid; 34 } 35 return r; 36 } 37 int main(){ 38 scanf("%I64d",&t); 39 makemiu(); 40 for (ll i=1;i<=t;i++){ 41 scanf("%I64d",&n); 42 printf("%I64d\n",getans(n)); 43 } 44 } View Code

转载于:https://www.cnblogs.com/g-word/p/3381255.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)