P3861 拆分

Sol

直接 DP 所有因子即可,因子个数只有 \(O(\sqrt{n})\) 个。

Code

#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define eb emplace_back
#define pf push_front
#define desktop "C:\\Users\\MPC\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
	if (y > x) return x = y,true;
	return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
	if (y < x) return x = y,true;
	return false;
}
LL power (LL a,LL b,LL p) {
	LL ans = 1;
	while (b) {
		if (b & 1) ans = ans * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return ans;
}
int fastio = (IOS,0);
#define endl '\n'
#define puts(s) cout << (s) << endl
const int N = 10010,MOD = 998244353;
LL n;
int m;
LL a[N];
unordered_map <LL,int> id;
LL f[N][N];
void mian () {
	cin >> n;
	m = 0;
	id.clear ();
	for (int i = 1;i <= n / i;i++) {
		if (n % i) continue;
		a[++m] = i;
		if (n / i != i) a[++m] = n / i;
	}
	sort (a + 1,a + m + 1);
	for (int i = 1;i <= m;i++) for (int j = 1;j <= m;j++) f[i][j] = 0;
	for (int i = 1;i <= m;i++) id[a[i]] = i,f[1][i] = 1;
	for (int i = 2;i <= m;i++) {
		for (int j = 1;j <= m;j++) {
			(f[i][j] += f[i][j - 1]) %= MOD;
			if (a[i] % a[j] == 0) (f[i][j] += f[id[a[i] / a[j]]][j - 1]) %= MOD;
		}
	}
	cout << (f[m][m] + MOD - 1) % MOD << endl;
}
int main () {
	int T = 1;
	cin >> T;
	while (T--) mian ();
	return 0;
}
posted @ 2025-05-20 17:18  incra  阅读(15)  评论(0)    收藏  举报