Lyft Level 5 Challenge 2018 - Elimination Round D
阿新 • • 發佈:2018-11-14
題目大意是給你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; }