「BZOJ1053」[HAOI2007] 反素数ant
Description
对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。
如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。
现在给定一个数N,你能求出不超过N的最大的反质数么?
Input
一个数N(1<=N<=2,000,000,000)。
Output
不超过N的最大的反质数。
Sample Input
1000
Sample Output
840
题解
本题似乎要先知道许多结论,不要问我证明。。
一个数约数个数=所有素因子的次数+1的乘积
举个例子就是48 = 2 ^ 4 * 3 ^ 1,所以它有(4 + 1) * (1 + 1) = 10个约数
然后可以通过计算得一个2000000000以内的数字不会有超过12个素因子
并且小素因子多一定比大素因子多要优
预处理出前12个素数直接爆搜即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include<iostream> #include<cstdio> #include<cstring> #define inf 0x7fffffff #define ll long long using namespace std; int n,ans=1,num=1; int p[15]={1,2,3,5,7,11,13,17,19,23,29,31}; void dfs(int k,ll now,int cnt,int last) { if(k==12) { if(now>ans&&cnt>num){ans=now;num=cnt;} if(now<=ans&&cnt>=num){ans=now;num=cnt;} return; } int t=1; for(int i=0;i<=last;i++) { dfs(k+1,now*t,cnt*(i+1),i); t*=p[k]; if(now*t>n)break; } } int main() { scanf("%d",&n); dfs(1,1,1,20); printf("%d",ans); return 0; } |
[…] 题解见黄学长:题解 […]
请问为什么last的初值为20?
这个我也不太记得了,可以设大一些吧