您的位置:首页 > 博客中心 > 互联网 >

Codeforces | CF1033D 【Divisors】

时间:2022-05-06 14:31

题目大意:给定\(n(1\leq n\leq500)\)个数\(a_1,a_2\cdots,a_n(1\leq a_i\leq2\cdot10^{18})\),每个数有\(3\sim5\)个因数,求\(\prod_{i=1}^{n}a_i\)的因数个数
这道题是一个交互题(虽说并不觉得有交互的必要...可能只是为了\(hack\)或者造数据方便吧),非常纯的数\((du)\)学\((liu)\),题目难度不在于结论,而在于代码实现
小学数学告诉我们以下结论:一个正整数\(x\)可以被分解成唯一形式\(x=p_{1}^{a_{1}}\cdot p_{2}^{a_{2}}\cdot \cdots \cdot p_{k}^{a_{k}}(p_i\text{为质数})\),\(x\)的因数个数为\(\prod_{i=1}^{k}(a_i+1)\).所以这道题的本质是质因数分解.
对于一个数\(x\)进行质因数分解最快的方式是枚举\(2\sim\sqrt{x}\)的质数\(p\)判断\(p\)是否能整除\(x\)进行分解,但是题目数据范围\(a_i\leq10^{18}\),如果要对\(a_i\)直接质因数分解需要枚举\(2\sim10^9\)内所有质数,若按照这种思路还需要预处理\(10^9\)内的质数表.
但是这样做并不可行,\(10^9\)内的质数表即使用线性筛也无法在\(1s\)和\(256M\)的限制内完成.此时注意到题目上还有未使用到的条件:每个数有\(3\sim5\)个因数.所以此题唯一的入手点就是这个具有奇特性质的条件.
考虑一个数\(x\)有\(3\sim5\)个因数可能的特殊性质,发现\(x\)有\((1)p_1\cdot p_2,(2)p_1^2,(3)p_1^3,(4)p_1^4\)四种可能的分解形式,对于\((2)(3)(4)\)三种分解形式,我们可以考虑二分求出\(p_1\)(\(cmath\)并不支持求\(\sqrt[3]{x},\sqrt[4]{x}\)),如果满足\((2)(3)(4)\)中任意一种分解,那么直接计数即可,如果三种分解形式都不满足,那么考虑对于\(p_1\cdot p_2\)形式的数的分解,如果\(p_1,p_2\)的次数都为\(1\)那么可以不分解这样的\(x\),直接乘\(2\times2\),如果\(p_1,p_2\)的次数有至少一个不为\(1\),那么对于\(x\)一定存在一个数\(y(y\neq x)\)使得\(gcd(x,y)>1\),此时的\(gcd(x,y)\)就是\(x,y\)的一个质因数,也即\(x,y\)都完成了质因数分解.至此所有可分解的数都完成了质因数分解,不可分解的数都满足两个质因数次数为\(1\),所以剩下的只需要求\(\prod_{i=1}^{k}(a_i+1)\)即可.
下面放\(AC\)代码\(\downarrow\downarrow\downarrow\)

#include//CF1033D
#include
#include
#include
#include
#include
#include
#include

using namespace std;

const int MOD=998244353;

int n;

long long a[502];

mapmp,mmp;

long long gcd(long long u,long long v){
    if(v==0){
        return u;
    }
    return gcd(v,u%v);
}

long long bs2(long long l,long long r,long long u){
    if(l==r){
        return l;
    }
    long long mid=(l+r)>>1;
    if(mid*mid>1;
    if(mid*mid*mid>1;
    if(mid*mid*mid*mid1){
                    mp[g]+=ite2.second+1;
                    mp[a[i]/g]++;
                    mp[ite2.first/g]+=ite2.second;
                    mmp[ite2.first]=0;
                    flag=true;
                    break;
                }
            }
            if(!flag){
                mmp[a[i]]++;
            }
        }
    }
    for(auto ite2:mmp){
        for(auto ite:mp){
            if(ite2.first%ite.first==0){
                mp[ite.first]+=ite2.second;
                mp[ite2.first/ite.first]+=ite2.second;
                mmp[ite2.first]=0;
                break;
            }
        }
    }
    long long ans=1;
    for(auto ite:mp){
        ans*=(ite.second+1);
        ans%=MOD;
    }
    for(auto ite:mmp){
        ans*=(ite.second+1);
        ans%=MOD;
        ans*=(ite.second+1);
        ans%=MOD;
    }
    printf("%lld\n",ans);
    fflush(stdout);
    return 0;
}

本类排行

今日推荐

热门手游