🍕🏠🌋 当前时间是:

 

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;
}
posted @ 2023-11-12 10:27  zzafanti  阅读(58)  评论(0)    收藏  举报
浏览器标题切换
浏览器标题切换end