P9836 种树
solution
首先要知道对于一个整数 \(a=p_{\alpha_1}^{\beta_1}p_{\alpha_2}^{\beta_2}\dots p_{\alpha_k}^{\beta_k}\),它的因数个数是 \(\prod\limits_{i=1}^k (\beta_i+1)\)。这一点可以通过组合意义证明。
又由于题目要求的是所有数上式的乘积,于是我们可以对值域内每个质数 \(p\) 考虑贡献。
如果数 \(a\) 所含的 \(p\) 的最高次幂的因子是 \(p^x\),那么如果再给 \(a\) 乘上一个 \(p\),答案就变为原来的 \(\dfrac{x+2}{x+1}\) 倍。显然 \(x\) 越小这个数越大,所以我们每次贪心地把 \(p\) 乘给 \(x\) 最小的数 \(a\),直接用小根堆动态维护所有 \(x\) 即可。
设值域为 \(W\),则时间复杂度为 \(O(\dfrac{W}{\ln W}\times n\log n)\approx O(nW)\),可以通过。
code
#include<bits/stdc++.h>
using namespace std;
using E=long long;
constexpr E mod=998244353;
int main(){
int n,w,W=0;
cin>>n>>w; W=max(W,w);
vector<int> p(n+1);
for(int i=1; i<=n; i++) cin>>p[i],W=max(W,p[i]);
E ans=1;
vector<bool> st(W+1);
for(int i=2; i<=W; i++){
if(st[i]) continue;
for(int j=i*2; j<=W; j+=i) st[j]=1;
priority_queue<int,vector<int>,greater<int>> pq;
for(int j=1; j<=n; j++){
int s=0;
while(p[j]%i==0) s++,p[j]/=i;
pq.push(s);
}
int cnt=0;
while(w%i==0) cnt++,w/=i;
while(cnt){
assert(pq.size());
int u=pq.top();
pq.pop();
pq.push(u+1);
cnt--;
}
while(pq.size()){
ans=ans*(pq.top()+1)%mod;
pq.pop();
}
}
cout<<ans<<endl;
return 0;
}

浙公网安备 33010602011771号