提高组模拟赛 50 B. 种树 & 洛谷 P9836 种树 题解
提高组模拟赛 50 B. 种树 题解
题目中的 \(p_i\) 在下文为避免歧义均称为 \(a_i\)。
\(a_i\) 和 \(w\) 都可以拆为质因数的形式来处理,即:
\[w=\prod p_k^{c_k}
\]
对于因数个数,有公式
\[sum=\prod_{i=1}^k (c_k+1)
\]
对于 \(a_i\),乘上一个质数 \(b\) 后,答案会增加
\[\frac{\prod_{i=1}^k (c_k+1)}{c^b+1}
\]
对于这个东西直接通过优先队列贪心维护即可,复杂度 \(O(n\sqrt n\log n)\)。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define eb emplace_back
#define mst(x, y) memset(x, y, sizeof(x))
#define pii pair<ll,ll>
#define fi first
#define se second
ll rd() {ll f=1,x=0;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}return f*x;}
void writ(ll x) {if(x<0){x=-x;putchar('-');}if(x>9)writ(x/10);putchar(x%10+'0');}
void wr(ll x) {writ(x);puts("");}
void wr_(ll x) {writ(x);putchar(' ');}
const ll N = 1e4+5, inf = 0x3f3f3f3f, M = 998244353;
ll n, w, ans;
ll p[N], v[N], g[N];
int f[N][N];
void calc(ll x, ll id) {
ll res = 0;
for(ll i = 1; i*i <= x; i++) if(x%i == 0) res += 2-(x/i==i);
g[id] = res;
for(ll i = 2; i <= x; i++) {
while(x%i == 0) {
f[id][i]++;
x /= i;
}
}
}
void solve() {
n = rd(), w = rd(), ans = 1;
ll ww = w;
for(ll i = 2; i <= w; i++) {
while(w%i == 0) {
v[i]++;
w /= i;
}
}
w = ww;
for(ll i = 1; i <= n; i++) {
p[i] = rd();
calc(p[i], i);
}
for(ll i = 2; i <= w; i++) {
if(!v[i]) continue;
priority_queue <pii> q;
for(ll j = 1; j <= n; j++) q.push({-(f[j][i]+1), j});
for(ll j = 1; j <= v[i]; j++) {
auto [v, x] = q.top(); q.pop();
v = -v;
g[x] = g[x]/v*(v+1);
q.push({-(v+1), x});
}
}
for(ll i = 1; i <= n; i++) ans = ans*g[i]%M;
wr(ans);
}
signed main() {
// freopen("plant.in", "r", stdin);
// freopen("plant.out", "w", stdout);
ll T = 1;
while(T--) solve();
return 0;
}

浙公网安备 33010602011771号