博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ】2440: [中山市选2011]完全平方数
阅读量:6703 次
发布时间:2019-06-25

本文共 1189 字,大约阅读时间需要 3 分钟。

【题意】T次询问第k小的非完全平方数倍数的数。T<=50,k<=10^9。(即无平方因子数——素因数指数皆为0或1的数)

【算法】数论(莫比乌斯函数)

【题解】考虑二分,转化为询问[1,x]中无平方因子数的个数(x最大为2n)。

运用容斥,答案ans=x - 1个素数的平方的倍数的数的个数 + 2个素数的乘积的平方的倍数的数的个数……

枚举i=[1,√x]的所有数字,系数是莫比乌斯函数,i的平方的倍数的数的个数就是n/(i^2)。

ans=x-Σμ(i)*n/(i^2),i∈[1,√x]

复杂度O(T*√n)。

注意:二分上届为2n,l+r会爆int。

#include
#include
#include
using namespace std;const int maxn=50010;int T,tot,n,miu[maxn],prime[maxn];bool mark[maxn];int main(){ scanf("%d",&T); miu[1]=1; for(int i=2;i<=50000;i++){ if(!mark[i]){prime[++tot]=i;miu[i]=-1;} for(int j=1;j<=tot&&i*prime[j]<=50000;j++){ mark[i*prime[j]]=1; if(i%prime[j]==0)break; miu[i*prime[j]]=-miu[i]; } } while(T--){ scanf("%d",&n); long long l=0,r=2*n,mid,ans;// while(l
>1;ans=0;int sq=(int)sqrt(mid); for(int i=1;i<=sq;i++){ ans+=miu[i]*mid/i/i; } if(ans>=n)r=mid;else l=mid+1; } printf("%lld\n",l); } return 0;}
View Code

 

定义集合x(素数)表示不是x^2的倍数的数字集合。

则要求集合并,容易知道集合交的补集。

转载于:https://www.cnblogs.com/onioncyc/p/8270389.html

你可能感兴趣的文章
数据存储和界面展示(二)
查看>>
修改 cmd 字体为 Consolas
查看>>
Linux中断 - tasklet
查看>>
Java第一章java语言的概述
查看>>
一道C#类型转换的思考题
查看>>
Linux运维工程师面试-部分题库
查看>>
Camera Calibration 相机标定:原理简介(三)
查看>>
Linux的proc文件系统详解
查看>>
Kubernetes集群(概念篇)
查看>>
Java动态代理和cglib动态代理
查看>>
POJ3274Gold Balanced Lineup(哈希)
查看>>
hdu - 3415 Max Sum of Max-K-sub-sequence
查看>>
JadClipse eclipse反编译插件
查看>>
struts2中文件上传
查看>>
男性早孕-从软件与程序的区别说起
查看>>
Windows 恢复环境(Windows RE模式)
查看>>
基于Annotation的输入校验
查看>>
Kinect for windows开发准备
查看>>
SQL Server 2012 官方培训课程体系
查看>>
为什么恍然大悟与知识管理的几个感触:人艰不拆
查看>>