Lyft Level 5 Challenge 2018 - Elimination Round D

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yqdjl6/article/details/82967953

题目大意是给你n个数,然后让你把n个数相乘,求乘积约数的个数,a[i]<=2e18。题目保证每个a[i]的约数在3到5个之间。这个条件很有用,因为一个数的约数最少为2个,1和它本身,所以可能情况只有4种pq,p的平方,p的三次方,p的四次方。后三个直接套就可以,第一个我们需要特殊处理一下,因为这种情况肯定是两个质数相乘,我们需要先判断p或q是否在其他a[j]中出现过,如果出现过,我们直接把p和q加上去就行,否则的话我们其实不用知道p和q是多少,我们只知道当前a[i]可以由两个数相乘得到,我们将数组中所有的a[i]得数量找到,那么这种情况的最终结果等于(sum+1)(sum+1)。感觉这题出的很巧妙。

#include<bits/stdc++.h>
using namespace std;
using LL = int64_t;
const LL mod = 998244353;
const int maxn=1e5+5;
map<LL,LL>mp,vis;
LL a[maxn];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int n;cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    LL ans=1;
    for(int i=1;i<=n;i++) {
        if(a[i]==1) continue;
        LL t=sqrtl(sqrtl(a[i]));
        if((t*t*t*t)==a[i]) mp[t]+=4;
        else {
            t=cbrtl(a[i]);
            if((t*t*t)==a[i]) mp[t]+=3;
            else {
                t=sqrtl(a[i]);
                if((t*t)==a[i]) mp[t]+=2;
                else {
                    LL p=-1;
                    for(int j=1;j<=n;j++) {
                        if(a[i]!=a[j]&&__gcd(a[i],a[j])!=1) {
                            p=__gcd(a[i],a[j]);break;
                        }
                    }
                    if(p!=-1) {
                        mp[p]++;
                        mp[a[i]/p]++;
                    }
                    else {
                        LL cnt=0;
                        if(vis.find(a[i])==vis.end()) {
                            for(int j=1;j<=n;j++) {
                                if(a[i]==a[j]) cnt++;
                            }
                            vis[a[i]]=1;
                            ans=ans*(cnt+1)%mod*(cnt+1)%mod;
                        }
                    }
                }
            }
        }
    }
    for(auto it :mp) {
        ans=(ans*(it.second+1))%mod;
    }
    cout<<ans;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yqdjl6/article/details/82967953
今日推荐