Bzoj P1053 [HAOI2007]反素数ant___dfs+思维

题目大意:

对于任何正整数x,其约数的个数记作g(x)。
当某个正整数x满足:g(x) > g(i) 且 0 < i < x,则称x为反质数。
现在给定一个数N,你能求出不超过N的最大的反质数
么?

1 <= N <= 2,000,000,000

分析:

这题其实并不难,不过比较难想得到,
设[1..N]中的一个数x,
我们将x质因数分解,
即x=p1^c1*p2^c2*……*pm^cm
则我们发现它的约数个数可以被表示为
(c1+1)(c2+1)……(cm+1)
这个自己想想就知道了,
因为要求约数个数最大,所以我们可以想到的就是,
假如一个合法的数y能够被
分成p1^c1*p2^c2且c2>c1,那么显然肯定
存在一个p1^c2*p2^c1比y小且约数个数相同
即满足c1≥c2≥……≥cm
所以指数肯定是单调递减的,且x的质因子是连续的若干个最小的质数,
因为x最大为2*10^9
我们可以发现
2*3*5*7*11*13*17*19*23*31 > 2*10^9
所以我们只需要对这10个质数的指数用dfs去确定即可

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long

using namespace std;

const LL num[11] = {2,3,5,7,11,13,17,19,23,29,31};
LL ans1,ans2;
int n;

void dfs(int x, LL dep, LL cp, int mi){
    if (x == 11){
        if ((cp > ans1) || (cp == ans1 && dep < ans2))
             ans1 = cp, ans2 = dep;
        return;  
    }
    LL rp = 1;
    for (int i = 0; i <= mi; i++){
         dfs(x+1, dep*rp,cp*(i+1), i);
         rp = rp*num[x];
         if (dep*rp > n) break;
    }   
}

int main(){
    scanf("%d",&n);
    dfs(0,1,1,31);
    printf("%d\n",ans2);
    return 0;
}


猜你喜欢

转载自blog.csdn.net/gx_man_vip/article/details/80259173
今日推荐