結果
| 問題 |
No.2137 Stairs of Permutation
|
| コンテスト | |
| ユーザー |
emthrm
|
| 提出日時 | 2022-11-25 23:30:24 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 22,585 bytes |
| コンパイル時間 | 3,128 ms |
| コンパイル使用メモリ | 257,520 KB |
| 最終ジャッジ日時 | 2025-02-09 00:55:38 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 11 TLE * 12 |
ソースコード
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
constexpr int INF = 0x3f3f3f3f;
constexpr long long LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr double EPS = 1e-8;
constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
constexpr int DY4[]{1, 0, -1, 0}, DX4[]{0, -1, 0, 1};
constexpr int DY8[]{1, 1, 0, -1, -1, -1, 0, 1};
constexpr int DX8[]{0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U>
inline bool chmax(T& a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U>
inline bool chmin(T& a, U b) { return a > b ? (a = b, true) : false; }
struct IOSetup {
IOSetup() {
std::cin.tie(nullptr);
std::ios_base::sync_with_stdio(false);
std::cout << fixed << setprecision(20);
}
} iosetup;
template <int M>
struct MInt {
unsigned int v;
MInt() : v(0) {}
MInt(const long long x) : v(x >= 0 ? x % M : x % M + M) {}
static constexpr int get_mod() { return M; }
static void set_mod(const int divisor) { assert(divisor == M); }
static void init(const int x = 10000000) {
inv(x, true);
fact(x);
fact_inv(x);
}
static MInt inv(const int n, const bool init = false) {
// assert(0 <= n && n < M && std::__gcd(n, M) == 1);
static std::vector<MInt> inverse{0, 1};
const int prev = inverse.size();
if (n < prev) {
return inverse[n];
} else if (init) {
// "n!" and "M" must be disjoint.
inverse.resize(n + 1);
for (int i = prev; i <= n; ++i) {
inverse[i] = -inverse[M % i] * (M / i);
}
return inverse[n];
}
int u = 1, v = 0;
for (unsigned int a = n, b = M; b;) {
const unsigned int q = a / b;
std::swap(a -= q * b, b);
std::swap(u -= q * v, v);
}
return u;
}
static MInt fact(const int n) {
static std::vector<MInt> factorial{1};
const int prev = factorial.size();
if (n >= prev) {
factorial.resize(n + 1);
for (int i = prev; i <= n; ++i) {
factorial[i] = factorial[i - 1] * i;
}
}
return factorial[n];
}
static MInt fact_inv(const int n) {
static std::vector<MInt> f_inv{1};
const int prev = f_inv.size();
if (n >= prev) {
f_inv.resize(n + 1);
f_inv[n] = inv(fact(n).v);
for (int i = n; i > prev; --i) {
f_inv[i - 1] = f_inv[i] * i;
}
}
return f_inv[n];
}
static MInt nCk(const int n, const int k) {
if (n < 0 || n < k || k < 0) return 0;
return fact(n) * (n - k < k ? fact_inv(k) * fact_inv(n - k) :
fact_inv(n - k) * fact_inv(k));
}
static MInt nPk(const int n, const int k) {
return n < 0 || n < k || k < 0 ? 0 : fact(n) * fact_inv(n - k);
}
static MInt nHk(const int n, const int k) {
return n < 0 || k < 0 ? 0 : (k == 0 ? 1 : nCk(n + k - 1, k));
}
static MInt large_nCk(long long n, const int k) {
if (n < 0 || n < k || k < 0) return 0;
inv(k, true);
MInt res = 1;
for (int i = 1; i <= k; ++i) {
res *= inv(i) * n--;
}
return res;
}
MInt pow(long long exponent) const {
MInt res = 1, tmp = *this;
for (; exponent > 0; exponent >>= 1) {
if (exponent & 1) res *= tmp;
tmp *= tmp;
}
return res;
}
MInt& operator+=(const MInt& x) {
if ((v += x.v) >= M) v -= M;
return *this;
}
MInt& operator-=(const MInt& x) {
if ((v += M - x.v) >= M) v -= M;
return *this;
}
MInt& operator*=(const MInt& x) {
v = static_cast<unsigned long long>(v) * x.v % M;
return *this;
}
MInt& operator/=(const MInt& x) { return *this *= inv(x.v); }
bool operator==(const MInt& x) const { return v == x.v; }
bool operator!=(const MInt& x) const { return v != x.v; }
bool operator<(const MInt& x) const { return v < x.v; }
bool operator<=(const MInt& x) const { return v <= x.v; }
bool operator>(const MInt& x) const { return v > x.v; }
bool operator>=(const MInt& x) const { return v >= x.v; }
MInt& operator++() {
if (++v == M) v = 0;
return *this;
}
MInt operator++(int) {
const MInt res = *this;
++*this;
return res;
}
MInt& operator--() {
v = (v == 0 ? M - 1 : v - 1);
return *this;
}
MInt operator--(int) {
const MInt res = *this;
--*this;
return res;
}
MInt operator+() const { return *this; }
MInt operator-() const { return MInt(v ? M - v : 0); }
MInt operator+(const MInt& x) const { return MInt(*this) += x; }
MInt operator-(const MInt& x) const { return MInt(*this) -= x; }
MInt operator*(const MInt& x) const { return MInt(*this) *= x; }
MInt operator/(const MInt& x) const { return MInt(*this) /= x; }
friend std::ostream& operator<<(std::ostream& os, const MInt& x) {
return os << x.v;
}
friend std::istream& operator>>(std::istream& is, MInt& x) {
long long v;
is >> v;
x = MInt(v);
return is;
}
};
using ModInt = MInt<MOD>;
#define cp_lib_4th(_1, _2, _3, x, ...) x
#define cp_lib_rep(i, l, r) for (int i = (l); (i) < (r); ++(i))
#define cp_lib_rep0(i, r) cp_lib_rep(i, 0, r)
#define rep(...) cp_lib_4th(__VA_ARGS__, cp_lib_rep, cp_lib_rep0, _)(__VA_ARGS__)
#define cp_lib_repr(i, r, l, ...) for (int i = (r); (i) >= (l); --(i))
#define repr(...) cp_lib_repr(__VA_ARGS__, 0)
#define all(a) ::begin(a),::end(a)
#define trav(a, b) for (auto&& a : (b))
using namespace std;
using ll = long long;
using ld = long double;
// [[maybe_unused]] static constexpr int INF = int(1e9 + 5);
[[maybe_unused]] static constexpr ll INFL = ll(INF) * INF;
template <class C> int sz(const C& c) { return int(::size(c)); }
#ifdef CP_LIB_DEBUG
#define cp_lib_assert(expr) \
do { if (!(expr)) { \
::cerr << "assertion failed: " << #expr << " (" << __FILE__ << ':' << __LINE__ << ")\n"; \
::abort(); \
} } while (0)
#else
#define cp_lib_assert(expr)
#endif
#if __cplusplus < 202002L
struct identity { template <class T> constexpr T&& operator()(T&& t) const noexcept { return forward<T>(t); }; };
#endif
#if __cpp_lib_remove_cvref < 201711L
template <class T> using remove_cvref_t = remove_cv_t<remove_reference_t<T>>;
#endif
namespace cp_lib_type_meta {
struct NoOp { template <class... Args> constexpr void operator()(Args&&...) const noexcept {} };
template <class T, class = void> constexpr bool is_tuple_like = false;
template <class T> constexpr bool is_tuple_like<T, void_t<tuple_element_t<0, T>>> = true;
}
namespace cp_lib_modint { struct ModIntTag {}; }
#include <unistd.h>
namespace cp_lib_io {
constexpr int BUF_SIZE = 1 << 20;
constexpr array<array<char, 4>, 10'000> DIGITS = []{
array<array<char, 4>, 10'000> digits{};
for (int i = 3, d = 1; i >= 0; --i, d *= 10)
rep(j, 10'000)
digits[j][i] = char('0' + j / d % 10);
return digits;
}();
array<char, BUF_SIZE> ibuf, obuf;
char *iptr = data(ibuf), *iend = iptr, *optr = data(obuf);
template <class T> constexpr bool is_std_array = false;
template <class T, size_t I> constexpr bool is_std_array<array<T, I>> = true;
void flush() {
for (auto* p = begin(obuf); p != optr; p += write(STDOUT_FILENO, p, optr - p));
optr = begin(obuf);
}
int _flush_atexit = []{ atexit(flush); return 0; }();
void refill() {
memmove(begin(ibuf), iptr, iend - iptr);
iend -= iptr - begin(ibuf);
iptr = begin(ibuf);
iend += read(STDIN_FILENO, iend, end(ibuf) - 1 - iend);
*iend = '\0';
}
template <class T, class T2 = remove_cvref_t<T>>
void print(T&& val) {
if (end(obuf) - optr < 64)
flush();
if constexpr (is_same_v<T2, char>)
*optr++ = val;
else if constexpr (is_same_v<T2, bool> || is_same_v<T2, vector<bool>::reference>)
return print(int(val));
else if constexpr (is_integral_v<T2> && is_signed_v<T2>) {
if (val < 0)
*optr++ = '-';
using U = make_unsigned_t<T2>;
return print(U(val < 0 ? -U(val) : U(val)));
} else if constexpr (is_integral_v<T2> && is_unsigned_v<T2>) {
T2 val2 = val;
array<char, 64> tmp;
char* tptr = end(tmp);
while (val2 >= 10'000)
tptr -= 4, memcpy(tptr, &DIGITS[val2 % 10'000][0], 4), val2 /= T2(10'000);
int d = (val2 >= 100 ? (val2 >= 1000 ? 4 : 3) : (val2 >= 10 ? 2 : 1));
memcpy(optr, &DIGITS[val2][4 - d], d);
memcpy(optr + d, tptr, end(tmp) - tptr);
optr += d + int(end(tmp) - tptr);
} else if constexpr (is_floating_point_v<T2>)
optr += sprintf(optr, "%.30Lf", (long double)val);
else if constexpr (is_convertible_v<T, string_view>) {
string_view sv(val);
if (sz(sv) + 1 <= end(obuf) - optr)
memcpy(optr, data(sv), sz(sv)), optr += sz(sv);
else {
flush();
for (auto *p = data(sv), *pe = p + sz(sv); p != pe; p += write(STDOUT_FILENO, p, pe - p));
}
} else if constexpr (is_base_of_v<cp_lib_modint::ModIntTag, T2>)
return print(decltype(T2::mod())(val));
else if constexpr (cp_lib_type_meta::is_tuple_like<T2> && !is_std_array<T2>)
return apply([](auto&&... items) { (print(items), ...); }, forward<T>(val));
else {
trav(item, val)
print(item);
return;
}
*optr++ = ' ';
}
template <class T>
void read(T& val) {
auto skip_ws = [] {
do {
for (; iptr != iend && *iptr <= ' '; ++iptr);
if (iend - iptr < 64)
refill();
} while (*iptr <= ' ');
};
auto read_other = [&](auto other) {
read(other);
return other;
};
if constexpr (is_same_v<T, char>)
skip_ws(), val = *iptr++;
else if constexpr (is_same_v<T, bool> || is_same_v<T, vector<bool>::reference>) {
val = bool(read_other(uint8_t()));
} else if constexpr (is_base_of_v<cp_lib_modint::ModIntTag, T>) {
val = T(read_other(ll()));
} else if constexpr (is_integral_v<T>) {
skip_ws();
if (is_signed_v<T> && *iptr == '-')
++iptr, val = T(-read_other(make_unsigned_t<T>()));
else
for (val = 0; iptr != iend && *iptr > ' '; val = T(10 * val + (*iptr++ & 15)));
} else if constexpr (is_floating_point_v<T>)
skip_ws(), val = T(strtold(iptr, &iptr));
else if constexpr (is_same_v<T, string>) {
skip_ws();
val.clear();
do {
auto* after = find_if(iptr, iend, [](char c) { return c <= ' '; });
val.append(iptr, after);
if ((iptr = after) != iend)
break;
refill();
} while (iptr != iend);
} else if constexpr (cp_lib_type_meta::is_tuple_like<T> && !is_std_array<T>)
apply([](auto&... items) { (read(items), ...); }, val);
else
trav(item, val)
read(item);
}
}
using cp_lib_io::flush;
template <class... Args>
void print(Args&&... args) { (cp_lib_io::print(forward<Args>(args)), ...); }
template <class... Args>
void println(Args&&... args) {
if (sizeof...(Args))
(cp_lib_io::print(forward<Args>(args)), ...), *(cp_lib_io::optr - 1) = '\n';
else
print('\n'), --cp_lib_io::optr;
}
template <class... Args>
void read(Args&... args) { (cp_lib_io::read(args), ...); }
template <class I>
constexpr enable_if_t<is_signed_v<I>, array<I, 3>> ext_gcd(I a, I b) {
I x(1), y(0), x1(0), y1(1);
while (b) {
I t = a / b;
tie(x, x1) = pair(x1, x - t * x1);
tie(y, y1) = pair(y1, y - t * y1);
tie(a, b) = pair(b, a - t * b);
}
return {a, x, y};
}
namespace cp_lib_modint {
template <class Self, class Int>
struct Base : ModIntTag {
static_assert(is_same_v<Int, uint32_t> || is_same_v<Int, uint64_t>);
friend constexpr Self operator+(Self l, Self r) { return l += r; }
friend constexpr Self operator-(Self l, Self r) { return l -= r; }
friend constexpr Self operator*(Self l, Self r) { return l *= r; }
friend constexpr Self operator/(Self l, Self r) { return l * r.inv(); }
friend constexpr Self& operator/=(Self& l, Self r) { return l *= r.inv(); }
friend constexpr Self operator+(Self x) { return x; }
friend constexpr Self operator-(Self x) { return Self(0) - x; }
friend constexpr Self& operator++(Self& x) { return x += Self(1); }
friend constexpr Self& operator--(Self& x) { return x -= Self(1); }
friend constexpr Self operator++(Self& x, int) { auto y = x; ++x; return y; }
friend constexpr Self operator--(Self& x, int) { auto y = x; --x; return y; }
#define CP_LIB_DEF(op) \
template <class T, enable_if_t<is_integral_v<T>, int> = 0> \
friend constexpr auto operator op(T l, Self r) { return Self(l) op r; }
CP_LIB_DEF(==) CP_LIB_DEF(!=) CP_LIB_DEF(<) CP_LIB_DEF(+) CP_LIB_DEF(-) CP_LIB_DEF(*) CP_LIB_DEF(/)
#undef CP_LIB_DEF
template <class T>
constexpr enable_if_t<is_integral_v<T>, Self> pow(T e) const {
Self r(1), b(*(Self*)(this));
for (; e; b *= b, e >>= 1)
if (e & 1) r *= b;
return r;
}
constexpr optional<Self> try_inv() const {
if (Self::is_prime())
return *(Self*)this == Self() ? nullopt : optional(pow(Self::mod() - 2));
auto [g, x, _] = ext_gcd(ll(*(Self*)this), ll(Self::mod()));
return (abs(g) == 1 ? optional(Self(x)) : nullopt);
}
constexpr Self inv() const {
if (Self::is_prime()) return pow(Self::mod() - 2);
auto [g, x, _] = ext_gcd(ll(*(Self*)this), ll(Self::mod()));
cp_lib_assert(abs(g) == 1);
return x;
}
friend ostream& operator<<(ostream& out, Self m) { return out << uint64_t(m); }
friend istream& operator>>(istream& in, Self& m) { ll x; in >> x; m = x; return in; }
protected:
Int i = 0;
};
template <class Int> using Wide = conditional_t<is_same_v<uint64_t, Int>, unsigned __int128, uint64_t>;
}
namespace cp_lib_modint {
template <class Int, Int Mod, bool IsPrime>
struct StaticMontgomery : public Base<StaticMontgomery<Int, Mod, IsPrime>, Int> {
static_assert(Mod % 2 && Mod < (1ull << (sizeof(Int) * 8 - 2)));
static constexpr Int INV = []{
Int inv = Mod;
rep(_, __builtin_ctz(sizeof(Int) * 8) - 1) inv *= 2 - Mod * inv;
return inv;
}();
static constexpr Int R2 = Int(-Wide<Int>(Mod) % Mod);
static constexpr Int reduce(Wide<Int> x) {
return Int((x - Int(x) * INV * Wide<Int>(Mod)) >> (sizeof(Int) * 8)) + Mod;
}
static constexpr Int norm(Int x) { return x >= Mod ? x - Mod : x; }
static constexpr Int mod() { return Mod; }
static constexpr bool is_prime() { return IsPrime; }
StaticMontgomery() = default;
template <class T, enable_if_t<is_unsigned_v<T>, int> = 0>
constexpr StaticMontgomery(T x) { this->i = reduce(Wide<Int>(uint64_t(x) % Mod) * R2); }
template <class T, enable_if_t<is_signed_v<T>, int> = 0>
constexpr StaticMontgomery(T x) { this->i = reduce(Wide<Int>(ll(x) % ll(Mod) + ll(Mod)) * R2); }
template <class T, enable_if_t<is_integral_v<T>, int> = 0>
constexpr explicit operator T() const { return T(norm(reduce(this->i))); }
constexpr Int raw() const { return norm(this->i); }
constexpr bool operator==(StaticMontgomery r) const { return norm(this->i) == norm(r.i); }
constexpr bool operator!=(StaticMontgomery r) const { return norm(this->i) != norm(r.i); }
constexpr bool operator<(StaticMontgomery r) const { return norm(this->i) < norm(r.i); }
constexpr StaticMontgomery& operator+=(StaticMontgomery r) {
if ((this->i += r.i) >= 2 * Mod)
this->i -= 2 * Mod;
return *this;
}
constexpr StaticMontgomery& operator-=(StaticMontgomery r) {
if (make_signed_t<Int>(this->i -= r.i) < 0)
this->i += 2 * Mod;
return *this;
}
constexpr StaticMontgomery& operator*=(StaticMontgomery r) {
this->i = reduce(Wide<Int>(this->i) * r.i);
return *this;
}
};
}
template <uint32_t Mod, bool IsPrime> using StaticMontgomeryInt = cp_lib_modint::StaticMontgomery<uint32_t, Mod, IsPrime>;
template <uint64_t Mod, bool IsPrime> using StaticMontgomeryInt64 = cp_lib_modint::StaticMontgomery<uint64_t, Mod, IsPrime>;
template <class T> constexpr inline bool is_pow2(T n) { return n && !(n & (n - 1)); }
template <class T> constexpr inline int floor_log2(T n) { return n ? 63 - __builtin_clzll(n) : 0; }
template <class T> constexpr inline int ceil_log2(T n) { return n ? floor_log2(n) + !is_pow2(n) : 0; }
template <class MI>
class NumberTheoreticTransform {
int max_exp;
array<array<array<MI, 30>, 31>, 2> z_step{};
public:
explicit NumberTheoreticTransform(MI g) : max_exp(min(30, __builtin_ctzll(MI::mod() - 1))) {
rep(w, max_exp) {
auto z_w = g.pow((MI::mod() - 1) >> (w + 1));
rep(i, w) {
int diff = (1 << (w - 1 - i)) - (((1 << i) - 1) << (w - i));
auto z = z_w.pow(abs(diff));
rep(inv, 2)
z_step[inv][w][i] = ((diff < 0) ^ inv ? z.inv() : z);
}
}
}
template <class It, class ItEnd>
void ntt_to_rev(It it, ItEnd it_end) const {
int n = int(it_end - it);
cp_lib_assert(is_pow2(n) && __builtin_ctz(n) <= max_exp);
for (int k = n >> 1, w = 0; k; k >>= 1, ++w) {
MI z = 1, a1;
for (int i = 0, x = 0; i < n; i += (k << 1), z *= z_step[0][w][__builtin_ctz(~x++)])
rep(j, i, i + k)
a1 = it[j + k] * z, it[j + k] = it[j] - a1, it[j] += a1;
}
}
template <class It, class ItEnd>
void intt_from_rev(It it, ItEnd it_end) const {
int n = int(it_end - it);
cp_lib_assert(is_pow2(n) && __builtin_ctz(n) <= max_exp);
for (int k = 1, w = __builtin_ctz(n) - 1; k < n; k <<= 1, --w) {
MI z = 1, a1;
for (int i = 0, x = 3 << w; i < n; i += 2 * k, z *= z_step[1][w][__builtin_ctz(--x)])
rep(j, i, i + k)
a1 = it[j + k], it[j + k] = (it[j] - a1) * z, it[j] += a1;
}
}
template <class ItA, class ItAEnd, class ItB, class ItBEnd>
vector<MI> convolution(ItA it_a, ItAEnd it_a_end, ItB it_b, ItBEnd it_b_end) const {
int la = int(it_a_end - it_a), lb = int(it_b_end - it_b), n = 1 << ceil_log2(la + lb - 1);
if (!la || !lb)
return {};
if (min(la, lb) < 32) {
vector<MI> a(la), b(lb), r(la + lb - 1);
transform(it_a, it_a_end, begin(a), [](auto&& x) { return MI(x); });
transform(it_b, it_b_end, begin(b), [](auto&& x) { return MI(x); });
rep(i, la) rep(j, lb)
r[i + j] += a[i] * b[j];
return r;
}
vector<MI> f(n), g(n);
transform(it_a, it_a_end, begin(f), [](auto&& x) { return MI(x); });
transform(it_b, it_b_end, begin(g), [](auto&& x) { return MI(x); });
ntt_to_rev(all(f));
ntt_to_rev(all(g));
auto inv_n = MI(n).inv();
rep(i, n)
f[i] *= g[i] * inv_n;
intt_from_rev(all(f));
f.resize(la + lb - 1);
return f;
}
};
template <class MI>
struct Combinatorics {
vector<MI> f, fi;
explicit Combinatorics(int n) : f(n + 1), fi(n + 1) {
f[0] = 1;
MI m; int i;
for (i = 1, m = f[0]; i <= n; ++i, ++m)
f[i] = f[i - 1] * m;
fi[n] = f[n].inv();
for (--i, --m; i; --i, --m)
fi[i - 1] = m * fi[i];
}
MI binom(int n, int k) const { return (n >= k && k >= 0 ? f[n] * fi[n - k] * fi[k] : MI(0)); }
MI stars_bars(int n, int k) const { return binom(n + k - 1, k - 1); }
MI catalan(int n) const { return f[2 * n] * fi[n + 1] * fi[n]; }
MI catalan(int n, int k) const { return (k ? k * f[2 * n + k - 1] * fi[n + k] * fi[n] : MI(!n)); }
template <class It, class ItEnd>
MI multinom(int n, It it, ItEnd it_end) const {
MI res = f[n];
while (it != it_end) res *= fi[*it++];
return res;
}
};
template <class MI>
vector<MI> taylor_shift(const vector<MI>& a, MI c, const Combinatorics<MI>& binom,
const NumberTheoreticTransform<MI>& ntt) {
int n = sz(a);
vector<MI> f(n), g(n);
MI pow_c = 1;
rep(i, n)
f[i] = binom.f[i] * a[i], g[n - 1 - i] = pow_c * binom.fi[i], pow_c *= c;
auto h = ntt.convolution(all(f), all(g));
rep(i, n)
f[i] = h[n + i - 1] * binom.fi[i];
return f;
}
template <class MI>
vector<MI> stirling_1st_kind(int n, const Combinatorics<MI>& binom,
const NumberTheoreticTransform<MI>& ntt) {
if (!n)
return {1};
auto a = stirling_1st_kind<MI>(n / 2, binom, ntt);
auto b = taylor_shift(a, -MI(n / 2), binom, ntt);
a = ntt.convolution(all(a), all(b));
if (n % 2)
b = {-MI(n - 1), 1}, a = ntt.convolution(all(a), all(b));
return a;
}
// https://judge.yosupo.jp/submission/77453
int main() {
int n; cin >> n;
using MI = StaticMontgomeryInt<998'244'353, true>;
NumberTheoreticTransform ntt(MI(3));
Combinatorics<MI> binom(n);
auto a = stirling_1st_kind(n, binom, ntt);
MI ans = 0;
for (int i = 1; i <= n; ++i) {
ans += ((n ^ i) & 1 ? -a[i] : a[i]) * i * i * i;
}
cout << ans << '\n';
return 0;
// FOR(n, 1, N) {
// vector<int> ways(n + 1, 0), a(n);
// iota(ALL(a), 0);
// do {
// int f = 0, max = -1;
// REP(i, n) f += chmax(max, a[i]);
// ++ways[f];
// } while (next_permutation(ALL(a)));
// REP(i, n + 1) cout << ways[i] << " \n"[i == n];
// }
}
emthrm