提出 #33320070


ソースコード 拡げる

#include <bits/stdc++.h>

#define eprintf(args...) fprintf(stderr, args)
#define rep(i, n) for (int i = 0; i < (int)(n); ++ i)

const int mod = 998244353;

inline int qpow(int x, int n) {
	int ans = 1;
	for (; n; n >>= 1, x = 1LL * x * x % mod)
		if (n & 1) ans = 1LL * ans * x % mod;
	return ans;
}

namespace fft {
;

const int mxn = 1 << 19;
int N;
int r[mxn];
int w[mxn];
inline void init(int n) {
	N = n;
	for (int i = 1; i < n - 1; ++ i)
		r[i] = r[i >> 1] >> 1 | (i & 1 ? n >> 1 : 0);
	for (int h = 1; h < n; h <<= 1) {
		int temp = qpow(3, (mod - 1) / (h << 1));
		rep(i, h) w[h + i] = i ? 1LL * temp * w[h + i - 1] % mod : 1;
	}
}
inline void dft(int a[], int n) {
	if (N != n) init(n);
	for (int i = 1; i < n - 1; ++ i)
		if (i < r[i]) std::swap(a[i], a[r[i]]);
	for (int h = 1; h < n; h <<= 1)
		for (int i = 0; i < n; i += h << 1)
			for (int j = 0; j < h; ++ j) {
				int v = 1LL * a[i + h + j] * w[h + j] % mod;
				a[i + h + j] = a[i + j] - v >= 0 ? a[i + j] - v : a[i + j] + mod - v;
				a[i + j] = a[i + j] + v < mod ? a[i + j] + v : a[i + j] + v - mod;
			}
}
inline void idft(int a[], int n) {
	dft(a, n);
	std::reverse(a + 1, a + n);
	int iv = qpow(n, mod - 2);
	rep(i, n) a[i] = 1LL * a[i] * iv % mod;
}

} // fft

struct poly : std::vector <int> {
	poly() { clear(); }
	poly(size_t n) { assign(n, 0); }
	poly(std::vector <int> v) { clear(); for (int x : v) push_back(x); }
	poly(std::initializer_list <int> v) { clear(); for (int x : v) push_back(x); }
	inline poly modn(size_t n) const { poly p(*this); p.resize(n); return p; }
	friend inline poly operator + (const poly &a, const poly &b) {
		poly c(std::max(a.size(), b.size()));
		rep(i, a.size()) c[i] = (c[i] + a[i]) % mod;
		rep(i, b.size()) c[i] = (c[i] + b[i]) % mod;
		return c;
	}
	friend inline poly operator - (const poly &a, const poly &b) {
		poly c(std::max(a.size(), b.size()));
		rep(i, a.size()) c[i] = (c[i] + a[i]) % mod;
		rep(i, b.size()) c[i] = (c[i] + mod - b[i]) % mod;
		return c;
	}
	friend inline poly operator * (const poly &a, const poly &b) {
		poly c(a.size() + b.size() - 1);
		int sz = 1;
		for (; sz < (int) c.size(); sz <<= 1);
		if (1LL * a.size() * b.size() <= 64LL * sz) {
			rep(i, a.size()) rep(j, b.size()) c[i + j] = (c[i + j] + 1LL * a[i] * b[j]) % mod;
		} else {
			static int A[fft::mxn], B[fft::mxn];
			rep(i, sz) A[i] = i < (int) a.size() ? a[i] : 0;
			rep(i, sz) B[i] = i < (int) b.size() ? b[i] : 0;
			fft::dft(A, sz);
			fft::dft(B, sz);
			rep(i, sz) A[i] = 1LL * A[i] * B[i] % mod;
			fft::idft(A, sz);
			rep(i, c.size()) c[i] = A[i];
		}
		return c;
	}
	friend inline poly inv(const poly &a) {
		if (a.size() == 1) return {qpow(a[0], mod - 2)};
		int n = a.size(), n0 = (n + 1) >> 1;
		poly a0 = a.modn(n0);
		poly b0 = inv(a0);
		return (b0 + b0 - a * b0 * b0).modn(n);
	}
};

const int mxn = 3e5 + 5;
int fac[mxn], ifac[mxn];

inline int comb(int n, int m) {
	return m < 0 || m > n ? 0 : 1LL * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

int n, K, a[mxn], cnt[mxn];

inline poly conq1(int l, int r) {
	if (l + 1 == r) {
		if (!cnt[l]) return {1};
		poly z(cnt[l] + 1);
		for (int i = 1; i <= cnt[l]; ++ i)
			z[i] = 1LL * fac[cnt[l]] * ifac[i] % mod * comb(cnt[l] - 1, cnt[l] - i) % mod;
		return z;
	}
	int m = (l + r) >> 1;
	return conq1(l, m) * conq1(m, r);
}

inline poly solve1() {
	poly g = conq1(0, n);
	rep(i, g.size()) g[i] = 1LL * g[i] * fac[i] % mod;
	poly f(n);
	rep(i, n) f[i] = g[n - i];
	return f;
}

inline poly solve2(poly g) {
	/*
	poly f(n);
	for (int i = 0; i < n; ++ i)
		for (int j = i; j < n; ++ j) {
			int cur = 1LL * comb(j, i) * g[j] % mod;
			if ((j - i) & 1) f[i] = (f[i] + mod - cur) % mod;
			else f[i] = (f[i] + cur) % mod;
		}
	return f;
	*/
	poly A(n), B(n);
	rep(i, n) A[i] = 1LL * g[i] * fac[i] % mod;
	rep(i, n) B[n - 1 - i] = 1LL * (i & 1 ? mod - 1 : 1) * ifac[i] % mod;
	poly C = A * B;
	poly f(n);
	rep(i, n) f[i] = 1LL * ifac[i] * C[i + n - 1] % mod;
	return f;
}

using frac = std::pair <poly, poly>;

inline frac conq3(const poly &c, int l, int r) {
	if (l + 1 == r) return {{c[l]}, {1, (mod - (n - 1 - l)) % mod}};
	int m = (l + r) >> 1;
	frac L = conq3(c, l, m), R = conq3(c, m, r);
	return {L.first * R.second + R.first * L.second, L.second * R.second};
}

inline poly solve3(poly c) {
	frac z = conq3(c, 0, n);
	poly f = ((z.first.modn(K)) * inv(z.second.modn(K))).modn(K);
	return f;
}

int main() {
	rep(i, mxn) fac[i] = i ? 1LL * i * fac[i - 1] % mod : 1;
	ifac[mxn - 1] = qpow(fac[mxn - 1], mod - 2);
	for (int i = mxn - 1; i; -- i) ifac[i - 1] = 1LL * i * ifac[i] % mod;
	scanf("%d %d", &n, &K), ++ K;
	rep(i, n) scanf("%d", &a[i]), -- a[i], cnt[a[i]] += 1;
	poly g = solve1();
	poly f = solve2(g);
	poly h = solve3(f);
	for (int i = 1; i < K; ++ i) printf("%d ", h[i]);
	printf("\n");
	return 0;
}

提出情報

提出日時
問題 Ex - Colorfulness
ユーザ bmb87978
言語 C++ (GCC 9.2.1)
得点 600
コード長 4961 Byte
結果 AC
実行時間 1255 ms
メモリ 32084 KiB

コンパイルエラー

./Main.cpp: In function ‘poly operator*(const poly&, const poly&)’:
./Main.cpp:74:33: warning: comparison of integer expressions of different signedness: ‘long long unsigned int’ and ‘long long int’ [-Wsign-compare]
   74 |   if (1LL * a.size() * b.size() <= 64LL * sz) {
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~
./Main.cpp: In function ‘int main()’:
./Main.cpp:165:7: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
  165 |  scanf("%d %d", &n, &K), ++ K;
      |  ~~~~~^~~~~~~~~~~~~~~~~
./Main.cpp:166:17: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
  166 |  rep(i, n) scanf("%d", &a[i]), -- a[i], cnt[a[i]] += 1;
      |            ~~~~~^~~~~~~~~~~~~

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 600 / 600
結果
AC × 3
AC × 19
セット名 テストケース
Sample 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt
All 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 01_small_00.txt, 01_small_01.txt, 01_small_02.txt, 02_random_00.txt, 02_random_01.txt, 02_random_02.txt, 02_random_03.txt, 02_random_04.txt, 02_random_05.txt, 02_random_06.txt, 02_random_07.txt, 02_random_08.txt, 02_random_09.txt, 02_random_10.txt, 02_random_11.txt, 02_random_12.txt
ケース名 結果 実行時間 メモリ
00_sample_00.txt AC 11 ms 5972 KiB
00_sample_01.txt AC 10 ms 6080 KiB
00_sample_02.txt AC 9 ms 6080 KiB
01_small_00.txt AC 19 ms 6284 KiB
01_small_01.txt AC 16 ms 6144 KiB
01_small_02.txt AC 17 ms 6332 KiB
02_random_00.txt AC 1026 ms 31780 KiB
02_random_01.txt AC 1054 ms 31692 KiB
02_random_02.txt AC 1076 ms 31696 KiB
02_random_03.txt AC 1125 ms 31696 KiB
02_random_04.txt AC 1223 ms 31780 KiB
02_random_05.txt AC 1124 ms 27720 KiB
02_random_06.txt AC 1197 ms 28152 KiB
02_random_07.txt AC 1195 ms 27664 KiB
02_random_08.txt AC 814 ms 28688 KiB
02_random_09.txt AC 841 ms 28832 KiB
02_random_10.txt AC 910 ms 29272 KiB
02_random_11.txt AC 1255 ms 31944 KiB
02_random_12.txt AC 1254 ms 32084 KiB