传送门酱:E Prime Gift
题意:给定一个集合
S={x|x=pk11pk22..pknn,ki∈N+}
其中 pi是给定的素数,n<=16,求这个集合里的第 k小元素,保证这个数小于 1018
(抱着今天的 CF 网络咕咕+B 题被 Hack 的咕咕心态来补之前的题 QAQ)
首先二分答案是很显然的,验证的话。。。我会 dfs(逃
考虑如何优化验证的过程
我们并不容易发现,我们可以把 16 个数分成两份,然后分别 dfs 记录到两个数组里,接着用双指针来计数就行了。(就是一个 meet in the middle 的思想)
现在就出现了一个问题,怎么分会不超时。
直觉告诉你肯定是平均分成两份舒服啦,而且要分得尽量平均(我的代码是第奇数个数为一组,第偶数个数为一组)
接着就要验证这样分会不会超时的问题。
易知笔算是没有用的,因为上下界差距太悬殊了,根本估不了,只能打代码 dfs
经过验证,8 个因子分别是 2,5,11,17,23,31,41,47,所有小于 1018的数有 1119429个,显然这种复杂度是可以接受的,因此我们就可以码代码了。
看了别的题解还有取前六个小一点的数一组,后 10 个数为一组的搞法,反正只要数字总数能接受就行。
鉴于这种东西并没有有效的用笔计算方法,因此我们要熟练掌握用 meet in the middle 爆搜的方法才能到考试的时候想到这样做。特别是复杂度是指数级别的时候,可以用这样的办法减少一半指数或者给指数开根号(开根号的有一个著名的栗子就是求最大团)
我感觉这篇好水呀 QAQ。。。
代码:
0 条评论