結果

問題 No.2381 Gift Exchange Party
ユーザー 遭難者遭難者
提出日時 2023-09-10 09:57:50
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 111 ms / 2,000 ms
コード長 9,754 bytes
コンパイル時間 9,087 ms
コンパイル使用メモリ 353,868 KB
実行使用メモリ 12,328 KB
最終ジャッジ日時 2024-06-28 01:25:18
合計ジャッジ時間 10,910 ms
ジャッジサーバーID
(参考情報)
judge4 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,816 KB
testcase_01 AC 2 ms
6,940 KB
testcase_02 AC 53 ms
7,588 KB
testcase_03 AC 26 ms
6,940 KB
testcase_04 AC 54 ms
7,940 KB
testcase_05 AC 109 ms
12,100 KB
testcase_06 AC 53 ms
7,704 KB
testcase_07 AC 53 ms
7,728 KB
testcase_08 AC 109 ms
12,136 KB
testcase_09 AC 5 ms
6,940 KB
testcase_10 AC 27 ms
6,940 KB
testcase_11 AC 53 ms
7,792 KB
testcase_12 AC 14 ms
6,940 KB
testcase_13 AC 53 ms
7,452 KB
testcase_14 AC 54 ms
7,912 KB
testcase_15 AC 26 ms
6,940 KB
testcase_16 AC 27 ms
6,940 KB
testcase_17 AC 107 ms
12,136 KB
testcase_18 AC 54 ms
7,772 KB
testcase_19 AC 53 ms
7,704 KB
testcase_20 AC 108 ms
12,300 KB
testcase_21 AC 107 ms
12,196 KB
testcase_22 AC 111 ms
12,068 KB
testcase_23 AC 108 ms
12,328 KB
testcase_24 AC 53 ms
7,676 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#ifndef DEBUG
#pragma GCC target("avx2")
#pragma GCC optimize("Ofast,unroll-loops")
#endif
#include <bits/stdc++.h>
#include <atcoder/all>
#define rep(i, n) for (int i = 0; i < n; i++)
#define ALL(a) a.begin(), a.end()
#define vc vector
#define ll long long
using namespace std;
using namespace atcoder;
template <class T>
vector<T> NTT(vector<T> a, vector<T> b)
{
	ll nmod = T::mod();
	int n = a.size();
	int m = b.size();
	vector<int> x1(n);
	vector<int> y1(m);
	for (int i = 0; i < n; i++)
	{
		ll tmp1, tmp2, tmp3;
		tmp1 = a[i].val();
		x1[i] = tmp1;
	}
	for (int i = 0; i < m; i++)
	{
		ll tmp1, tmp2, tmp3;
		tmp1 = b[i].val();
		y1[i] = tmp1;
	}
	auto z1 = convolution<167772161>(x1, y1);
	auto z2 = convolution<469762049>(x1, y1);
	auto z3 = convolution<1224736769>(x1, y1);
	vector<T> res(n + m - 1);
	constexpr ll m1 = 167772161;
	constexpr ll m2 = 469762049;
	constexpr ll m3 = 1224736769;
	constexpr ll m1m2 = 104391568;
	constexpr ll m1m2m3 = 721017874;
	ll mm12 = m1 * m2 % nmod;
	for (int i = 0; i < n + m - 1; i++)
	{
		int v1 = (z2[i] - z1[i]) * m1m2 % m2;
		if (v1 < 0)
			v1 += m2;
		int v2 = (z3[i] - (z1[i] + v1 * m1) % m3) * m1m2m3 % m3;
		if (v2 < 0)
			v2 += m3;
		res[i] = (z1[i] + v1 * m1 + v2 * mm12);
	}
	return res;
}
template <class T>
struct FormalPowerSeries : vector<T>
{
	using vector<T>::vector;
	using F = FormalPowerSeries;
	F& operator=(const vector<T>& g)
	{
		int n = g.size();
		int m = (*this).size();
		if (m < n)
			(*this).resize(n);
		for (int i = 0; i < n; i++)
			(*this)[i] = g[i];
		return (*this);
	}
	F& operator=(const F& g)
	{
		int n = g.size();
		int m = (*this).size();
		if (m < n)
			(*this).resize(n);
		for (int i = 0; i < n; i++)
			(*this)[i] = g[i];
		return (*this);
	}
	F& operator-()
	{
		for (int i = 0; i < (*this).size(); i++)
			(*this)[i] *= -1;
		return (*this);
	}
	F& operator+=(const F& g)
	{
		int n = (*this).size();
		int m = g.size();
		if (n < m)
			(*this).resize(m);
		for (int i = 0; i < m; i++)
			(*this)[i] += g[i];
		return (*this);
	}
	F& operator+=(const T& r)
	{
		if ((*this).size() == 0)
			(*this).resize(1);
		(*this)[0] += r;
		return (*this);
	}
	F& operator-=(const F& g)
	{
		int n = (*this).size();
		int m = g.size();
		if (n < m)
			(*this).resize(m);
		for (int i = 0; i < m; i++)
			(*this)[i] -= g[i];
		return (*this);
	}
	F& operator-=(const T& r)
	{
		if ((*this).size() == 0)
			(*this).resize(1);
		(*this)[0] -= r;
		return (*this);
	}
	F& operator*=(const F& g)
	{
		(*this) = convolution((*this), g);
		return (*this);
	}
	F& operator*=(const T& r)
	{
		for (int i = 0; i < (*this).size(); i++)
			(*this)[i] *= r;
		return (*this);
	}
	F& operator/=(const F& g)
	{
		int n = (*this).size();
		(*this) = convolution((*this), g.inv());
		(*this).resize(n);
		return (*this);
	}
	F& operator/=(const T& r)
	{
		r = r.inv();
		for (int i = 0; i < (*this).size(); i++)
			(*this)[i] *= r;
		return (*this);
	}
	F& operator<<=(const int d)
	{
		int n = (*this).size();
		(*this).insert((*this).begin(), d, 0);
		(*this).resize(n);
		return *this;
	}
	F& operator>>=(const int d)
	{
		int n = (*this).size();
		(*this).erase((*this).begin(), (*this).begin() + min(n, d));
		(*this).resize(n);
		return *this;
	}
	F operator*(const T& g) const { return F(*this) *= g; }
	F operator-(const T& g) const { return F(*this) -= g; }
	F operator+(const T& g) const { return F(*this) += g; }
	F operator/(const T& g) const { return F(*this) /= g; }
	F operator*(const F& g) const { return F(*this) *= g; }
	F operator-(const F& g) const { return F(*this) -= g; }
	F operator+(const F& g) const { return F(*this) += g; }
	F operator/(const F& g) const { return F(*this) /= g; }
	F operator%(const F& g) const { return F(*this) %= g; }
	F operator<<(const int d) const { return F(*this) <<= d; }
	F operator>>(const int d) const { return F(*this) >>= d; }
	F pre(int sz) const
	{
		return F(begin(*this), begin(*this) + min((int)this->size(), sz));
	}
	F inv(int deg = -1) const
	{
		int n = (*this).size();
		if (deg == -1)
			deg = n;
		assert(n > 0 && (*this)[0] != T(0));
		F g(1);
		g[0] = (*this)[0].inv();
		while (g.size() < deg)
		{
			int m = g.size();
			F f(begin(*this), begin(*this) + min(n, 2 * m));
			F r(g);
			f.resize(2 * m);
			r.resize(2 * m);
			internal::butterfly(f);
			internal::butterfly(r);
			for (int i = 0; i < 2 * m; i++)
				f[i] *= r[i];
			internal::butterfly_inv(f);
			f.erase(f.begin(), f.begin() + m);
			f.resize(2 * m);
			internal::butterfly(f);
			for (int i = 0; i < 2 * m; i++)
				f[i] *= r[i];
			internal::butterfly_inv(f);
			T in = T(2 * m).inv();
			in *= -in;
			for (int i = 0; i < m; i++)
				f[i] *= in;
			g.insert(g.end(), f.begin(), f.begin() + m);
		}
		return g.pre(deg);
	}
	T eval(const T& a)
	{
		T x = 1;
		T ret = 0;
		for (int i = 0; i < (*this).size(); i++)
		{
			ret += (*this)[i] * x;
			x *= a;
		}
		return ret;
	}
	void onemul(const int d, const T c)
	{
		int n = (*this).size();
		for (int i = n - d - 1; i >= 0; i--)
		{
			(*this)[i + d] += (*this)[i] * c;
		}
	}
	void onediv(const int d, const T c)
	{
		int n = (*this).size();
		for (int i = 0; i < n - d; i++)
		{
			(*this)[i + d] -= (*this)[i] * c;
		}
	}
	F diff() const
	{
		int n = (*this).size();
		F ret(n);
		for (int i = 1; i < n; i++)
			ret[i - 1] = (*this)[i] * i;
		ret[n - 1] = 0;
		return ret;
	}
	F integral() const
	{
		int n = (*this).size(), mod = T::mod();
		vector<T> inv(n);
		inv[1] = 1;
		for (int i = 2; i < n; i++)
			inv[i] = T(mod) - inv[mod % i] * (mod / i);
		F ret(n);
		for (int i = n - 2; i >= 0; i--)
			ret[i + 1] = (*this)[i] * inv[i + 1];
		ret[0] = 0;
		return ret;
	}
	F log(int deg = -1) const
	{
		int n = (*this).size();
		if (deg == -1)
			deg = n;
		assert((*this)[0] == T(1));
		return ((*this).diff() * (*this).inv(deg)).pre(deg).integral();
	}
	F exp(int deg = -1) const
	{
		int n = (*this).size();
		if (deg == -1)
			deg = n;
		assert(n == 0 || (*this)[0] == 0);
		F Inv;
		Inv.reserve(deg);
		Inv.push_back(T(0));
		Inv.push_back(T(1));
		auto inplace_integral = [&](F& f) -> void
			{
				const int n = (int)f.size();
				int mod = T::mod();
				while (Inv.size() <= n)
				{
					int i = Inv.size();
					Inv.push_back((-Inv[mod % i]) * (mod / i));
				}
				f.insert(begin(f), T(0));
				for (int i = 1; i <= n; i++)
					f[i] *= Inv[i];
			};
		auto inplace_diff = [](F& f) -> void
			{
				if (f.empty())
					return;
				f.erase(begin(f));
				T coeff = 1, one = 1;
				for (int i = 0; i < f.size(); i++)
				{
					f[i] *= coeff;
					coeff++;
				}
			};
		F b{ 1, 1 < (int)(*this).size() ? (*this)[1] : 0 }, c{ 1 }, z1, z2{ 1, 1 };
		for (int m = 2; m <= deg; m <<= 1)
		{
			auto y = b;
			y.resize(2 * m);
			internal::butterfly(y);
			z1 = z2;
			F z(m);
			for (int i = 0; i < m; i++)
				z[i] = y[i] * z1[i];
			internal::butterfly_inv(z);
			T si = T(m).inv();
			for (int i = 0; i < m; i++)
				z[i] *= si;
			fill(begin(z), begin(z) + m / 2, T(0));
			internal::butterfly(z);
			for (int i = 0; i < m; i++)
				z[i] *= -z1[i];
			internal::butterfly_inv(z);
			for (int i = 0; i < m; i++)
				z[i] *= si;
			c.insert(end(c), begin(z) + m / 2, end(z));
			z2 = c;
			z2.resize(2 * m);
			internal::butterfly(z2);
			F x(begin((*this)), begin((*this)) + min<int>((*this).size(), m));
			x.resize(m);
			inplace_diff(x);
			x.push_back(T(0));
			internal::butterfly(x);
			for (int i = 0; i < m; i++)
				x[i] *= y[i];
			internal::butterfly_inv(x);
			for (int i = 0; i < m; i++)
				x[i] *= si;
			x -= b.diff();
			x.resize(2 * m);
			for (int i = 0; i < m - 1; i++)
				x[m + i] = x[i], x[i] = T(0);
			internal::butterfly(x);
			for (int i = 0; i < 2 * m; i++)
				x[i] *= z2[i];
			internal::butterfly_inv(x);
			T si2 = T(m << 1).inv();
			for (int i = 0; i < 2 * m; i++)
				x[i] *= si2;
			x.pop_back();
			inplace_integral(x);
			for (int i = m; i < min<int>((*this).size(), 2 * m); i++)
				x[i] += (*this)[i];
			fill(begin(x), begin(x) + m, T(0));
			internal::butterfly(x);
			for (int i = 0; i < 2 * m; i++)
				x[i] *= y[i];
			internal::butterfly_inv(x);
			for (int i = 0; i < 2 * m; i++)
				x[i] *= si2;
			b.insert(end(b), begin(x) + m, end(x));
		}
		return b.pre(deg);
	}
	F pow(ll m)
	{
		int n = (*this).size();
		if (m == 0)
		{
			F ret(n);
			ret[0] = 1;
			return ret;
		}
		int x = 0;
		while (x < n && (*this)[x] == T(0))
			x++;
		if (x >= (n + m - 1) / m)
		{
			F ret(n);
			return ret;
		}
		F f(n - x);
		T y = (*this)[x];
		for (int i = x; i < n; i++)
			f[i - x] = (*this)[i] / y;
		f = f.log();
		for (int i = 0; i < n - x; i++)
			f[i] *= m;
		f = f.exp();
		y = y.pow(m);
		for (int i = 0; i < n - x; i++)
			f[i] *= y;
		F ret(n);
		const ll xm = x * m;
		for (int i = xm; i < n; i++)
			ret[i] = f[i - xm];
		return ret;
	}
	F shift(T c)
	{
		int n = (*this).size();
		int mod = T::mod();
		vector<T> inv(n + 1);
		inv[1] = 1;
		for (int i = 2; i <= n; i++)
			inv[i] = mod - inv[mod % i] * (mod / i);
		T x = 1;
		for (int i = 0; i < n; i++)
		{
			(*this)[i] *= x;
			x *= (i + 1);
		}
		F g(n);
		T y = 1;
		T now = 1;
		for (int i = 0; i < n; i++)
		{
			g[n - i - 1] = now * y;
			now *= c;
			y *= inv[i + 1];
		}
		auto tmp = convolution(g, (*this));
		T z = 1;
		for (int i = 0; i < n; i++)
		{
			(*this)[i] = tmp[n + i - 1] * z;
			z *= inv[i + 1];
		}
		return (*this);
	}
};
using mint = modint998244353;
using fps = FormalPowerSeries<mint>;
void solve() {
	int n, p;
	cin >> n >> p;
	fps a(n + 1);
	a[1] = 1;
	if (p <= n)
		a[p] = mint(p).inv();
	mint fac = 1;
	rep(i, n) fac *= i + 1;
	mint ans = (1 - a.exp()[n]) * fac;
	cout << ans.val() << '\n';
}
int main() {
	// srand((unsigned)time(NULL));
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout << fixed << setprecision(40);
	solve();
	return 0;
}
0