[LuoguP1221]最多因子数

Posted yeasio-nein

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LuoguP1221]最多因子数相关的知识,希望对你有一定的参考价值。

[Luogu1221]最多因子数(Link

求区间[L,R]内约数个数最多的数和它的约数个数。

这个题吧,乍一看确实不是很难,然后稍微一想,嗯,是个傻*题。这是唯一感受,不要问我为什么。

首先我们定义一个函数(F(X))表示(X)的约数个数。题目要求求出([L,R])中的(F(X)max)和这个数。首先最基本我们要知道每一个数(Data[i])都一个基本性质:

(Data[i] = Prime_1^{M_1} imes Prime_2^{M_2} imes ... imes Prime_N^{M_N}),语言表示就是任意i一个数都可以分解成多个质数的若干次方的乘积,稍微搞一搞我们得到(F(X) = (M_1 + 1) imes (M_2 + 1) imes ... imes (M_N + 1))

由此将搜索的过程由质因数分解转化为了质因数相乘,则搜索的时候只需要搜索质因数就可以了,然后记录质因数的个数即可。当然,单纯这样搞是会(T)掉的,下面数一下剪枝:

  1. 按照递增顺序搜索每一个质数。
  2. 枚举质数的指数。如果当前枚举的质数算上指数的乘积为(X),下一次枚举的时候指数为(Y),如果(X imes Y > R),超过了区间的右端点,直接(return?)。这个是很显而易见的。
  3. 如果当前的质数算上指数的乘积在([L, R])之间,那么代表它有可能更新答案,而(R - L < X)的时候,我们也直接(return),因为下一次搜索一定搜不到([L, R])之间的数,所以zhi直接跳出。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std ;
typedef long long LL ;
const int MAXN = 500010 ;
const int MAXM = 40000 ;
int L, R, Ans, Max, Prime[MAXN] ;
bool NotP[MAXN] ; int Tot ;

inline void Dfs(LL H, LL N, LL Now) {
    if (H > Tot || N > R) return ;
    int K = (int)(log(R / double(N)) / log(double(Prime[H]))) ;
    if (Now * (1 << K) < Ans) return ;
    if (N >= L && (Now > Ans || (Now == Ans && N < Max))) 
        Ans = Now, Max = N ;
    LL X = 1 ;
    for (int i = 1 ; i <= K ; i ++) X *= Prime[H] ;
    for (int i = K + 1 ; i >= 1 ; i --) {
        Dfs(H + 1, N * X, Now * i) ;
        X /= Prime[H] ;
    }   return ;
}

int main() {
    scanf("%d %d", & L, & R) ;
    if (L == R && L == 1) {
        printf("Between %d and %d, 1 has a maximum of 1 divisors.
", L, R);
        return 0 ;
    }
    for (int i = 2 ; i <= MAXM ; i ++) {
        if (! NotP[i]) {
            Prime[++ Tot] = i ; 
            for (int j = i << 1 ; j <= MAXM ; j += i) 
                NotP[j] = true ;
        }
    }
    if (R - L <= 10000) {
        for (int i = L ; i <= R ; i ++) {
            int T = 2 ;
            for (int j = 2 ; j * j <= i ; j ++) {
                if (j * j == i) T ++ ;
                else if (i % j == 0) T += 2 ;
            }   if (T > Ans) Ans = T, Max = i ;
        }
    }
    else Dfs(1, 1, 1) ;
    printf("Between %d and %d, %d has a maximum of %d divisors.
", L, R, Max,Ans);
    return 0 ;
}

以上是关于[LuoguP1221]最多因子数的主要内容,如果未能解决你的问题,请参考以下文章

[luoguP2774] 方格取数问题(最大点权独立集)

C++中一个数的最大因子怎么找?

luoguP1004 方格取数(四维DP)

[luoguP2704] 炮兵阵地(状压DP)

luoguP2822组合数问题

luoguP4068 [SDOI2016]数字配对