2024jxcpc D.Magic LCM (logn筛质因子)
题目链接
#include<bits/stdc++.h>
using namespace std;
#define int long long
using ll=long long;
typedef pair<int,int>PII;
typedef priority_queue<int> upq;
typedef priority_queue<int,vector<int>,greater<int>> dpq;
const int M=998244353;
const int N=1e6+20; // 只要处理(1e6)的质因子 // 样例:
/*51 4 5 2 1034 */
bool prime[N];
int mi[N]; //筛出i的最小质因子
void getprime(){for(int i=2;i<N;i++){if(prime[i]) continue;for(int j=i*2;j<N;j+=i){prime[j]=1;if(mi[j]==0)mi[j]=i;}mi[i]=i;}mi[1]=1;
}int cnt[N][21];
int mx[N+1]; // 质数i最大出现次数
void solved()
{int n; cin>>n;vector<int>v(n);for(int i=0;i<n;i++) cin>>v[i];ll ans=0;vector<int>stk;for(int i=0;i<n;i++){while(v[i]>1){int p=mi[v[i]];int tt=0;while(mi[v[i]]==p){v[i]/=p;tt++;}if(mx[p]==0) stk.push_back(p); mx[p]=max(mx[p],tt);cnt[p][tt]++; //为p的质数tt次幂出现的次数}}vector<ll>a(n,1);for(auto p:stk){int j=0; // 含有质数p的个数for(int i=mx[p];i>0;i--) j+=cnt[p][i];ll pw=1;for(int i=1;i<=mx[p];i++){pw*=p;pw%=M;while(cnt[p][i]){cnt[p][i]--;a[--j]*=pw; //大的放a[0]; a[j]%=M;}}mx[p]=0;}for(auto i:a) ans=(ans+i)%M;cout<<ans<<"\n";}
signed main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);getprime();int t; cin>>t;while(t--) solved();
}