题意:给定数m,将m分解成若干个数的乘积,将原数ai乘上这些数,使得处理后的因子数乘积最大,求贡献。复杂度要求
解法:
可以令,有状态,结合特殊性质可以拿到65pts
正解:
质因数分解
讨论最终的贡献。对于每个数x,记f i,j 表示第i个数被质因数j分解的次数。当这个质因数分解次数固定时,将m对当前质数分解,被分解后分解次数+1,优先分解次数较小的数。比如2*3->3*3,->2*4,显然后续贡献较小,则有,因为
,次数会多一次
#include<bits/stdc++.h>
#define int long long
#define rep(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
const int N = 1e4 + 10 , M = 1500 , mod = 998244353;
int n,w,a[N],pri[N],cnt,ans=1;
bool v[N];
void ai(){
for(int i=2;i<N;i++){
if(!v[i]){
v[i]=true;pri[++cnt]=i;
for(int j=2;i*j<N;j++)
v[i*j]=true;
}
}
}
int f[M][N];priority_queue<int,vector<int>,greater<int> > q;
signed main(){
cin>>n>>w;
ai();
rep(i,1,n){
int x;
cin>>x;
if(x>1){
rep(j,1,cnt){
//cout<<pri[j]<<endl;
while(x%pri[j]==0){
f[j][i]++;
x/=pri[j];
}
}
}
}
rep(T,1,cnt){
rep(i,1,n) q.push(f[T][i]);
while(w%pri[T]==0){
int t=q.top();q.pop();
q.push(++t);w/=pri[T];
}while(q.size()){
cout<<q.top()+1<<" ";
ans*=(q.top()+1);ans%=mod;
q.pop();
}cout<<endl;
}cout<<ans;
return 0;
}
几点补充:将数x分解成后,它的因子数为,那么只要分解m即可