标题是不是看不懂?没关系,简单来说就是毛子大学冬令营的题。
题面看不懂?没关系,我来讲述题意:
给定一个数n,一开始筐子A里有1~n一共n个数。假如A中某两个数的gcd不是1,那么这两个数可以一起放到筐子B里。
求(A中的数量+B中的数量/2)最小的数值.
构造题。
显然,尽可能让B中多A中少一定会让答案更优。
仔细观察,发现大于$\frac{n}{2}$的数之间任意的gcd都是1。
那么我们枚举所有数的最大质因数p,并把它加入到集合$S[p]$中。
比如说n=9。刨除1不算,我们得到集合:$S[2]=2,4,8$,$S[3]=3,6,9$,$S[1]=1,5,7$。
注意,其中$S[1]$并不是表示最大质因数p是1,只是表示本身为质数或者1。另外由于是枚举的质因数,所以x不是质数的$S[x]$中一定没有元素。
简单分析可以得出两个性质:对于x>n/2的所有集合$S[x]$都不会有任何元素。除了$S[1]$以外的集合每个集合都至少有2个数。
证明:
大于n/2的数如果不是质数,那么它的最大质因数一定小于n/2,所属的集合一定是某个$S[x]$,其中$x<=\frac{n}{2}$。如果是质数,那么它所属的集合就是$S{1}$。
对于小于n/2的一个质数x,$S[x]$一定至少包含两个元素:x和2x。
这样一来,除了$S[1]$以外的集合每个集合都至少有2个数:p和2p。根据不同情况还可能有$3p,4p,......kp$。反正不会少于2个就是啦。
根据刚才的性质可以得到:对于集合p如果元素个数是偶数,那么两两配对扔到B中。否则将其中必定存在的元素2p扔到$S[0]$这个特殊的集合中代以后使用。
在上面的操作完成后,我们考虑$S[0]$中的集合。因为$S[0]$中的元素都是形如2p这种形式,所以gcd最少也是2。因此他们也可以两两配对。如果$S[0]$的元素个数是奇数特判一下就好啦。
至于剩下的$S[1]$这个集合。我们只能把他们全部留在筐子A中。
根据上面的算法,假设1~n之间的质数个数为m,那么答案显然是(m+(n-m+1)/2)。
现在问题转化为了求1~n之间的质数的个数。($n<=1e11$)
线性筛什么的不可能,这个数据范围我们只能想亚线性做法,比如......min25筛。
如果会min25筛的人这道题到此就可以愉快的AC了。
不会的人有两种选择:
1.去学min25筛。
2.我们充分运用分块打表的思想,提前求出$(1,\sqrt n)$,$(\sqrt n +1,\sqrt n +\sqrt n)$,......这些区间的质数个数,打个表。
然后问题转化为了求一个区间长度小于$1e6$,但n为$1e11$的某个区间的质数个数。
这个问题便是普及组算法了。
至此,我们已经将一个省选难度的题转化为了普及组难度的题。代码写完就轻松AC啦。