社区讨论

TLE 90pts 求调

P12321[蓝桥杯 2024 国研究生组] 生成树问题参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mlkqyjnq
此快照首次捕获于
2026/02/13 18:30
6 天前
此快照最后确认于
2026/02/13 18:47
6 天前
查看原帖
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;

using i32 = int32_t;
using i64 = int64_t;
using ui32 = uint32_t;
using ui64 = uint64_t;

namespace strdp {
	const int N = 3e5, mod = 998244353;
	int n, lm, f[N + 5], cnt[N + 5], d[N + 5];
	inline int qpow(int x, int y) {
		int res = 1;
		while (y) {
			if (y & 1) res = res * x % mod;
			x = x * x % mod;
			y >>= 1;
		}
		return res;
	}
	int rev[(1 << 19) + 5];
	inline void ntt(vector<int> &a, int lm, int typ) {
		int hgbit = 0;
		while ((1 << hgbit) < lm) hgbit++;
		for (int i = 0; i < lm; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (hgbit - 1));
		for (int i = 0; i < lm; i++) {
			if (i < rev[i]) {
				swap(a[i], a[rev[i]]);
			}
		}
		for (int m = 1; m < lm; m *= 2) {
			int gn = qpow(3, (mod - 1) / (m * 2));
			if (typ == -1) gn = qpow(gn, mod - 2);
			for (int i = 0; i < lm; i += m * 2) {
				int w = 1;
				for (int j = 0; j < m; j++, w = w * gn % mod) {
					int x = a[i + j], y = w * a[i + j + m] % mod;
					a[i + j] = (x + y) % mod;
					a[i + j + m] = (x - y + mod) % mod;
				}
			}
		}
		if (typ == -1) {
			int inv = qpow(lm, mod - 2);
			for (int i = 0; i < lm; i++) a[i] = a[i] * inv % mod;
		}
	}
	inline vector<int> mul(vector<int> &a, vector<int> &b) {
		int lm = 1;
		while (lm < a.size() + b.size() - 1) lm <<= 1;
		a.resize(lm), b.resize(lm);
		ntt(a, lm, 1);
		ntt(b, lm, 1);
		for (int i = 0; i < lm; i++) a[i] = a[i] * b[i] % mod;
		ntt(a, lm, -1);
		return a;
	}
	vector<pair<int, int>> qwq;
	vector<int> cdq(int l, int r) {
		if (l == r) return {qwq[l].first, qwq[l].second};
		int mid = l + r >> 1;
		vector<int> resl = cdq(l, mid);
		vector<int> resr = cdq(mid + 1, r);
		return mul(resl, resr);
	}
	void main() {
		cin >> n;
		if (n == 1) {
			cout << 1 << "\n";
			return;
		}
		for (int i = 1; i <= n; i++) f[i] = i;
		for (int i = 2; i <= n / i; i++) {
			for (int j = i * i; j <= n; j += i * i) {
				while (f[j] % (i * i) == 0) f[j] /= i * i;
			}
		}
		for (int i = 1; i <= n; i++) {
			d[i] = cnt[f[i]];
			cnt[f[i]]++;
		}
		for (int i = 2; i <= n; i++) qwq.push_back({i - 1 - d[i], d[i]});
		vector<int> res = cdq(0, n - 2);
		for (int i = 0; i < n; i++) cout << res[i] << "\n";
	}
}

i32 main() {

	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

	int t = 1;
	// cin >> t;

	while (t--) strdp::main();
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...