[HAOI2007]反素数 题解

[HAOI2007]反素数 题解

题目地址:洛谷:【P1463】[HAOI2007]反素数 – 洛谷、BZOJ:Problem 1053. — [HAOI2007]反素数ant

题目描述

对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。
如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。
现在给定一个数N,你能求出不超过N的最大的反质数么?

输入输出格式

输入格式:
一个数N(1<=N<=2,000,000,000)。

输出格式:
不超过N的最大的反质数。

输入输出样例

输入样例#1:

1000

输出样例#1:

840

题解

我们注意到如果将一个数分解成质数幂的乘积即 \displaystyle x = \prod p_i^{k_i} ,它因数的个数实际上就是 \displaystyle \prod (k_i + 1)
考虑到质因数较小的数比较有利,答案一定存在于质因数最小的数中,而前11个质数的乘积实际上已经超过了n的范围,我们可以把前11个质数打个小表,DFS来选择每个质数的数量,寻找答案。

代码

// Code by KSkun, 2018/5
#include <cstdio>
#include <cctype>

typedef long long LL;

inline char fgc() {
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
}

inline LL readint() {
    register LL res = 0, neg = 1;
    register char c = fgc();
    while(!isdigit(c)) {
        if(c == '-') neg = -1;
        c = fgc();
    }
    while(isdigit(c)) {
        res = (res << 1) + (res << 3) + c - '0';
        c = fgc();
    }
    return res * neg;
}

const int prime[] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};

int n, ans, acnt;

inline void dfs(LL x, int cnt, int lim, int step) {
    if(step == 12) {
        if((x > ans && cnt > acnt) || (x <= ans && cnt >= acnt)) {
            ans = x; acnt = cnt;
        }
        return;
    }
    LL t = 1;
    for(int i = 0; i <= lim; i++) {
        if(x * t > n) break;
        dfs(x * t, cnt * (i + 1), lim, step + 1);
        t *= prime[step];
    }
}

int main() {
    n = readint();
    dfs(1, 1, 20, 1);
    printf("%d", ans);
    return 0;
}


发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据