codeforces 300E Empire Strikes Back 数论+二分查找

本文介绍了一种算法问题的解决思路,通过质因数分解将给定的一系列数转换为质因子的乘积形式,并利用二分搜索找出满足特定条件的最小数值。文章详细阐述了解决方案的实现过程和技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给定N个数a1,a2,a3...aN,现在要求最小的n满足 n!/(a1!*a2!*...*aN!) 是一个正整数的最小的n。

分析:这题的想法很明确,就是分解a1!*a2!*...*aN!,把其分解成质因子相乘的形式,这个都很熟悉了,然后就是对每一个质因子二分搜索出一个数字下界,最后求其中最大的一个数,问题的关键就是如何分解这样一个表达式成一个质因子相乘的形式。使用一个cnt数组来表示每一个数的在乘积中出现的次数,然后从后往前假设一个数出现了k次,那么如果这个数是素数则不用更新,如果一个数是合数则将其分解成两部分,一个是该数最小的质因子,一个是除以这个质因子之后的值,接着一直做下去,就能够把所有的素因子全部统计起来,最后再对每一个素因子都二分搜索。

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <cmath>
#include <vector>
using namespace std;

typedef long long LL;
const int N = 10000005;
vector<int>vv;
LL cnt[N];
int p[N];
int Max;
LL sum;
int n;

void pre() {
    for (int i = 2; i < N; ++i) {
        if (!p[i]) {
            p[i] = i;
            vv.push_back(i);
        }
        for (int j = 0; i*vv[j] < N; ++j) {
            p[i*vv[j]] = vv[j];
            if (i % vv[j] == 0) break;
        }
    }
}

LL cal(LL mid, LL base) {
    LL ret = 0;
    while (mid) {
        ret += (mid /= base);
    }
    return ret;
}

void deal() {
    for (int i = Max; i >= 2; --i) {
        if (p[i] != i) {
            cnt[p[i]] += cnt[i];
            cnt[i/p[i]] += cnt[i];
        }
    }
}

LL get(LL base, LL x) {
    LL l = 1, r = sum;
    LL ret;
    while (l <= r) {
        LL mid = (l + r) >> 1;
        if (cal(mid, base) >= x) {
            ret = mid;
            r = mid - 1;
        } else {
            l = mid + 1;
        }
    }
    return ret;
}

int main() {
    pre();
    scanf("%d", &n);
    int x;
    for (int i = 0; i < n; ++i) {
        scanf("%d", &x);
        sum += x;
        Max = max(Max, x);
        ++cnt[x];
    }
    for (int i = Max-1; i >= 2; --i) {
        cnt[i] += cnt[i+1];
    } // 模拟阶乘,1-n之间每个数都有一个 
    deal();
    LL ret = 1;
    for (int i = 0; i < vv.size(); ++i) {
        ret = max(ret, get(vv[i], cnt[vv[i]]));
    }
    printf("%I64d\n", ret);
    return 0;
} 

 

GPU Device Id: 0x1002 0x67DF 113-58085STD1-M81 C940 Polaris20 XTX A1 GDDR5 256Mx32 8GB 300e/300m (C) 1988-2010, Advanced Micro Devices, Inc. ATOMBIOSBK-AMD VER015.050.002.001.000000 5808STD1.M81 CCC Overdrive Limits GPU Clock: 2000 MHz Memory Clock: 2250 MHz PowerTune Limit: -50% to +50% Limits TDP: 145 W TDC Power: 142 A Battery Power: 145 W Small Power Power: 145 W Max. Power Limit: 145 W Max. Temp: 90°C GPU Clocks 300 MHz, 600 MHz, 900 MHz, 997 MHz 1021 MHz, 1052 MHz, 1091 MHz, 1150 MHz Memory Clocks 300 MHz, 1000 MHz, 2050 MHz Temperature Target: 75 °C Memory Support 8192 MB, GDDR5, Autodetect 8192 MB, GDDR5, Samsung K4G80325FB 8192 MB, GDDR5, Micron MT51J256M32HFB Memory Timings (Samsung) tRCDW-tRCDWA-tRCDR-tRCDRA-tRC-tCL-tRFC 250 MHz: 2-3-3-3-11-8-27 400 MHz: 3-3-5-5-17-9-43 600 MHz: 5-5-8-8-26-11-65 900 MHz: 7-7-13-13-39-15-98 1000 MHz: 8-8-14-14-43-16-109 1125 MHz: 9-9-16-16-49-17-123 1250 MHz: 10-10-18-18-55-18-137 1375 MHz: 12-12-20-20-61-19-151 1500 MHz: 13-13-22-22-65-20-164 1625 MHz: 14-14-24-24-71-21-178 1750 MHz: 16-16-26-26-77-22-192 2000 MHz: 17-17-29-29-87-24-219 Memory Timings (Micron) tRCDW-tRCDWA-tRCDR-tRCDRA-tRC-tCL-tRFC 200 MHz: 0-3-2-3-7-7-21 300 MHz: 0-3-4-4-12-7-32 400 MHz: 0-3-5-5-15-7-43 800 MHz: 5-5-11-11-31-11-87 1000 MHz: 9-9-14-14-39-13-109 1250 MHz: 13-13-18-18-50-16-137 1375 MHz: 15-15-20-20-55-17-151 1500 MHz: 17-17-22-22-60-18-164 1625 MHz: 19-19-24-24-65-19-178 1750 MHz: 17-17-22-22-60-18-164 1875 MHz: 21-21-26-26-70-20-192 2000 MHz: 19-19-24-24-65-19-178
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值