294 - Divisors(唯一分解定律)

来源:互联网 发布:性价比 实木家具 知乎 编辑:程序博客网 时间:2024/04/30 08:18

该题运用了唯一分解定律,详情请见lrj紫书P321,一个数的约数的个数就是将该数唯一分解之后,各质因子的系数+1之积 。虽然有一个快速算每一个数的约数个数的欧拉phi函数值,但是该题的数据范围非常大,数组存不下,而且区间差非常小,显然事先算出每一个数的约数个数不是一个明智的决定。 所以我们用的时候再算也不迟。  那么我们需要事先打出素数表,要多少素数呢? sqrt(10^9)就够了,因为如果一个素数比这个值还大,那么她的平方肯定超过了10^9,不在数据范围内,得到的系数一定是1,相当于没有乘。

细节参见代码:

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 55555;int T,n,m,cnt = 0,vis[maxn+5],prime[maxn+5];ll a,b;void init() {    int m = sqrt(maxn+0.5);    for(int i=2;i<=m;i++) if(!vis[i])        for(int j=i*i;j<=maxn;j+=i) vis[j] = 1;    for(int i=2;i<=maxn;i++) if(!vis[i])        prime[cnt++] = i;}ll C(int n,int cnt) {    ll sum = 1;    for(int i=0;i<cnt;i++) {        int cur = 1;        while(n % prime[i] == 0) {            n /= prime[i];            cur++;        }        sum *= cur;    }    return sum;}int main() {    init();    scanf("%d",&T);    while(T--) {        ll ans = 0, res = 1;        scanf("%lld%lld",&a,&b);        for(ll i = a; i <= b; ++i) {            ll cur = C(i,cnt);            if(cur > ans) {                ans = cur;                res = i;            }        }        printf("Between %lld and %lld, %lld has a maximum of %lld divisors.\n",a,b,res,ans);    }    return 0;}


0 0
原创粉丝点击