提高组模拟赛 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;
}
posted @ 2025-11-28 10:48  Hirasawayuiii  阅读(0)  评论(0)    收藏  举报