Problem:
F: n 角錐グラフ
問題
$n$ 角錐グラフを以下のように定義する。
頂点数は $n + 1$ である。
頂点 $0$ と自身を除くすべての頂点との間に、重み付きの無向辺が張られている。
頂点 $1, 2, …, n$ はこの順にサイクルとなるように、重み付きの無向辺が張られている。
あなたは $n$ 角錐グラフ上の頂点 $0$ を出発し、異なる $k$ 個の辺を通って頂点 $0$ に戻ってくる必要がある。一度通った辺は，たとえ向きが異なっても二度と通ることはできない。
同じ頂点を何回通っても構わないし、途中で頂点 $0$ を通っても構わない。
これを満たす道順を良いサーキットと呼ぶ。より形式的には、以下のように定義される。
$n$ 角錐グラフの辺からなる集合を $E$ とよび、辺 $e \in E$ の重みを $w(e)$ と書く。
ここで、$n$ 角錐グラフの頂点の列 $(v_1, …, v_{k + 1})$ であり、以下の条件を満たすものを長さ $k$ の
良いサーキット
とよぶ。
すべての $1 \leq i \leq k$ に対して $\{v_i, v_{i + 1}\} \in E$
$v_1 = v_{k + 1} = 0$
すべての $1 \leq i, j \leq k$ に対して、$i \neq j$ ならば $\{v_i, v_{i + 1}\} \neq \{v_j, v_{j + 1}\}$
また、長さ $k$ の良いサーキットの
コスト
を、通った辺の重みの総和 $\sum_{i = 1}^{k} w(\{v_i, v_{i + 1}\})$ と定義する。
長さ $k$ の良いサーキットすべてについてコストを求め、その総和を $998244353$ で割った余りを出力せよ。長さ $k$ の良いサーキットが存在しない場合は、$0$ を出力せよ。
ただし、二つの長さ $k$ の良いサーキット $(v_1, …, v_{k + 1})$ と $(v'_1, …, v'_{k + 1})$ が異なるとは、$v_i \neq v'_i$ を満たす $i$ ($1 \leq i \leq k+1$) が存在することを言う。
入力形式
入力は $3$ 行からなる。
$1$ 行目には $n$ と $k$ が空白区切りで与えられる。
$2$ 行目と $3$ 行目には、$n$ 角錐グラフの重みを表す長さ $n$ の配列 $A=(a_1, ..., a_n)$ と $B=(b_1, ..., b_n)$ がそれぞれ空白区切りで与えられる。
$a_i$ は、辺 $\{0, i\}$ の重みを表し、$b_i$ は、辺 $\{i, i + 1\}$（ただし、$i = n$ のときは 辺 $\{n, 1\}$）の重みを表す。
$n$ $k$
$a_1$ ... $a_n$
$b_1$ ... $b_n$
制約
入力は全て整数で与えられる
$3 \leq n \leq 10^6$
$3 \leq k \leq 2n$
$1 \leq a_i, b_i \leq 10^9$
出力形式
長さ $k$ の良いサーキットすべてに対してコストを求め、その総和を $998244353$ で割った余りを一行に出力せよ。良いサーキットが存在しない場合は $0$ を一行に出力せよ。
入力例1
3 4
1 2 3
4 4 4
出力例1
72
この入力例は上図の $3$ 角錐グラフを表す。
長さ $4$ の良いサーキットとコストは全部で $6$ 個存在する。
$(0, 1, 2, 3, 0)$
$(0, 2, 3, 1, 0)$
$(0, 3, 1, 2, 0)$
$(0, 3, 2, 1, 0)$
$(0, 1, 3, 2, 0)$
$(0, 2, 1, 3, 0)$
コストはそれぞれ、$12$、$11$、$13$、$12$、$11$、$13$ である。
よって、これらを足し合わせた $72$ を出力する。
入力例2
4 6
1 1 3 4
4 3 1 2
出力例2
224
長さ $6$ の良いサーキットの一例として、$(0, 1, 2, 0, 3, 4, 0)$ が挙げられる。

Submitted solutions:

code_snippet: #ifndef HIDDEN_IN_VS // 折りたたみ用

// 警告の抑制
#define _CRT_SECURE_NO_WARNINGS

// ライブラリの読み込み
#include <bits/stdc++.h>
using namespace std;

// 型名の短縮
using ll = long long; using ull = unsigned long long; // -2^63 ～ 2^63 = 9e18（int は -2^31 ～ 2^31 = 2e9）
using pii = pair<int, int>;	using pll = pair<ll, ll>;	using pil = pair<int, ll>;	using pli = pair<ll, int>;
using vi = vector<int>;		using vvi = vector<vi>;		using vvvi = vector<vvi>;	using vvvvi = vector<vvvi>;
using vl = vector<ll>;		using vvl = vector<vl>;		using vvvl = vector<vvl>;	using vvvvl = vector<vvvl>;
using vb = vector<bool>;	using vvb = vector<vb>;		using vvvb = vector<vvb>;
using vc = vector<char>;	using vvc = vector<vc>;		using vvvc = vector<vvc>;
using vd = vector<double>;	using vvd = vector<vd>;		using vvvd = vector<vvd>;
template <class T> using priority_queue_rev = priority_queue<T, vector<T>, greater<T>>;
using Graph = vvi;

// 定数の定義
const double PI = acos(-1);
int DX[4] = { 1, 0, -1, 0 }; // 4 近傍（下，右，上，左）
int DY[4] = { 0, 1, 0, -1 };
int INF = 1001001001; ll INFL = 4004004003094073385LL; // (int)INFL = INF, (int)(-INFL) = -INF;

// 入出力高速化
struct fast_io { fast_io() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(18); } } fastIOtmp;

// 汎用マクロの定義
#define all(a) (a).begin(), (a).end()
#define sz(x) ((int)(x).size())
#define lbpos(a, x) (int)distance((a).begin(), std::lower_bound(all(a), (x)))
#define ubpos(a, x) (int)distance((a).begin(), std::upper_bound(all(a), (x)))
#define Yes(b) {cout << ((b) ? "Yes\n" : "No\n");}
#define rep(i, n) for(int i = 0, i##_len = int(n); i < i##_len; ++i) // 0 から n-1 まで昇順
#define repi(i, s, t) for(int i = int(s), i##_end = int(t); i <= i##_end; ++i) // s から t まで昇順
#define repir(i, s, t) for(int i = int(s), i##_end = int(t); i >= i##_end; --i) // s から t まで降順
#define repe(v, a) for(const auto& v : (a)) // a の全要素（変更不可能）
#define repea(v, a) for(auto& v : (a)) // a の全要素（変更可能）
#define repb(set, d) for(int set = 0, set##_ub = 1 << int(d); set < set##_ub; ++set) // d ビット全探索（昇順）
#define repis(i, set) for(int i = lsb(set), bset##i = set; i < 32; bset##i -= 1 << i, i = lsb(bset##i)) // set の全要素（昇順）
#define repp(a) sort(all(a)); for(bool a##_perm = true; a##_perm; a##_perm = next_permutation(all(a))) // a の順列全て（昇順）
#define uniq(a) {sort(all(a)); (a).erase(unique(all(a)), (a).end());} // 重複除去
#define EXIT(a) {cout << (a) << endl; exit(0);} // 強制終了
#define inQ(x, y, u, l, d, r) ((u) <= (x) && (l) <= (y) && (x) < (d) && (y) < (r)) // 半開矩形内判定

// 汎用関数の定義
template <class T> inline ll powi(T n, int k) { ll v = 1; rep(i, k) v *= n; return v; }
template <class T> inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; } // 最大値を更新（更新されたら true を返す）
template <class T> inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; } // 最小値を更新（更新されたら true を返す）
template <class T> inline T getb(T set, int i) { return (set >> i) & T(1); }
template <class T> inline T smod(T n, T m) { n %= m; if (n < 0) n += m; return n; } // 非負mod

// 演算子オーバーロード
template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template <class T> inline istream& operator>>(istream& is, vector<T>& v) { repea(x, v) is >> x; return is; }
template <class T> inline vector<T>& operator--(vector<T>& v) { repea(x, v) --x; return v; }
template <class T> inline vector<T>& operator++(vector<T>& v) { repea(x, v) ++x; return v; }

#endif // 折りたたみ用


#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;

#ifdef _MSC_VER
#include "localACL.hpp"
#endif

using mint = modint998244353;
//using mint = static_modint<(int)1e9+7>;
//using mint = modint; // mint::set_mod(m);

using vm = vector<mint>; using vvm = vector<vm>; using vvvm = vector<vvm>; using vvvvm = vector<vvvm>; using pim = pair<int, mint>;
#endif


#ifdef _MSC_VER // 手元環境（Visual Studio）
#include "local.hpp"
#else // 提出用（gcc）
int mute_dump = 0;
int frac_print = 0;
#if __has_include(<atcoder/all>)
namespace atcoder {
	inline istream& operator>>(istream& is, mint& x) { ll x_; is >> x_; x = x_; return is; }
	inline ostream& operator<<(ostream& os, const mint& x) { os << x.val(); return os; }
}
#endif
inline int popcount(int n) { return __builtin_popcount(n); }
inline int popcount(ll n) { return __builtin_popcountll(n); }
inline int lsb(int n) { return n != 0 ? __builtin_ctz(n) : 32; }
inline int lsb(ll n) { return n != 0 ? __builtin_ctzll(n) : 64; }
inline int msb(int n) { return n != 0 ? (31 - __builtin_clz(n)) : -1; }
inline int msb(ll n) { return n != 0 ? (63 - __builtin_clzll(n)) : -1; }
#define dump(...)
#define dumpel(v)
#define dump_math(v)
#define input_from_file(f)
#define output_to_file(f)
//#define Assert(b) { if (!(b)) { vc MLE(1<<30); EXIT(MLE.back()); } } // RE の代わりに MLE を出す
#endif

#define Assert(b) assert(b)

//【階乗など（法が大きな素数）】
/*
* Factorial_mint(int N) : O(n)
*	N まで計算可能として初期化する．
*
* mint fact(int n) : O(1)
*	n! を返す．
*
* mint fact_inv(int n) : O(1)
*	1/n! を返す（n が負なら 0 を返す）
*
* mint inv(int n) : O(1)
*	1/n を返す．
*
* mint perm(int n, int r) : O(1)
*	順列の数 nPr を返す．
*
* mint perm_inv(int n, int r) : O(1)
*	順列の数の逆数 1/nPr を返す．
*
* mint bin(int n, int r) : O(1)
*	二項係数 nCr を返す．
*
* mint bin_inv(int n, int r) : O(1)
*	二項係数の逆数 1/nCr を返す．
*
* mint mul(vi rs) : O(|rs|)
*	多項係数 nC[rs] を返す．（n = Σrs）
*
* mint hom(int n, int r) : O(1)
*	重複組合せの数 nHr = n+r-1Cr を返す（0H0 = 1 とする）
*
* mint neg_bin(int n, int r) : O(1)
*	負の二項係数 nCr = (-1)^r -n+r-1Cr を返す（n ≦ 0, r ≧ 0）
*
* mint pochhammer(int x, int n) : O(1)
*	ポッホハマー記号 x^(n) を返す（n ≧ 0）
*
* mint pochhammer_inv(int x, int n) : O(1)
*	ポッホハマー記号の逆数 1/x^(n) を返す（n ≧ 0）
*/
class Factorial_mint {
	int n_max;

	// 階乗と階乗の逆数の値を保持するテーブル
	vm fac, fac_inv;

public:
	// n! までの階乗とその逆数を前計算しておく．O(n)
	Factorial_mint(int n) : n_max(n), fac(n + 1), fac_inv(n + 1) {
		// verify : https://atcoder.jp/contests/dwacon6th-prelims/tasks/dwacon6th_prelims_b

		fac[0] = 1;
		repi(i, 1, n) fac[i] = fac[i - 1] * i;

		fac_inv[n] = fac[n].inv();
		repir(i, n - 1, 0) fac_inv[i] = fac_inv[i + 1] * (i + 1);
	}
	Factorial_mint() : n_max(0) {} // ダミー

	// n! を返す．
	mint fact(int n) const {
		// verify : https://atcoder.jp/contests/dwacon6th-prelims/tasks/dwacon6th_prelims_b

		Assert(0 <= n && n <= n_max);
		return fac[n];
	}

	// 1/n! を返す（n が負なら 0 を返す）
	mint fact_inv(int n) const {
		// verify : https://atcoder.jp/contests/abc289/tasks/abc289_h

		Assert(n <= n_max);
		if (n < 0) return 0;
		return fac_inv[n];
	}

	// 1/n を返す．
	mint inv(int n) const {
		// verify : https://atcoder.jp/contests/exawizards2019/tasks/exawizards2019_d

		Assert(n > 0);
		Assert(n <= n_max);
		return fac[n - 1] * fac_inv[n];
	}

	// 順列の数 nPr を返す．
	mint perm(int n, int r) const {
		// verify : https://atcoder.jp/contests/abc172/tasks/abc172_e

		Assert(n <= n_max);

		if (r < 0 || n - r < 0) return 0;
		return fac[n] * fac_inv[n - r];
	}

	// 順列の数 nPr の逆数を返す．
	mint perm_inv(int n, int r) const {
		// verify : https://yukicoder.me/problems/no/3139

		Assert(n <= n_max);
		Assert(0 <= r); Assert(r <= n);

		return fac_inv[n] * fac[n - r];
	}

	// 二項係数 nCr を返す．
	mint bin(int n, int r) const {
		// verify : https://judge.yosupo.jp/problem/binomial_coefficient_prime_mod

		Assert(n <= n_max);
		if (r < 0 || n - r < 0) return 0;
		return fac[n] * fac_inv[r] * fac_inv[n - r];
	}

	// 二項係数の逆数 1/nCr を返す．
	mint bin_inv(int n, int r) const {
		// verify : https://www.codechef.com/problems/RANDCOLORING

		Assert(n <= n_max);
		Assert(r >= 0);
		Assert(n - r >= 0);
		return fac_inv[n] * fac[r] * fac[n - r];
	}

	// 多項係数 nC[rs] を返す．
	mint mul(const vi& rs) const {
		// verify : https://yukicoder.me/problems/no/2141

		if (*min_element(all(rs)) < 0) return 0;
		int n = accumulate(all(rs), 0);
		Assert(n <= n_max);

		mint res = fac[n];
		repe(r, rs) res *= fac_inv[r];

		return res;
	}

	// 重複組合せの数 nHr = n+r-1Cr を返す（0H0 = 1 とする）
	mint hom(int n, int r) {
		// verify : https://mojacoder.app/users/riantkb/problems/toj_ex_2

		if (n == 0) return (int)(r == 0);
		if (r < 0 || n - 1 < 0) return 0;
		Assert(n + r - 1 <= n_max);
		return fac[n + r - 1] * fac_inv[r] * fac_inv[n - 1];
	}

	// 負の二項係数 nCr を返す（n ≦ 0, r ≧ 0）
	mint neg_bin(int n, int r) {
		// verify : https://atcoder.jp/contests/abc345/tasks/abc345_g

		if (n == 0) return (int)(r == 0);
		if (r < 0 || -n - 1 < 0) return 0;
		Assert(-n + r - 1 <= n_max);
		return (r & 1 ? -1 : 1) * fac[-n + r - 1] * fac_inv[r] * fac_inv[-n - 1];
	}

	// ポッホハマー記号 x^(n) を返す（n ≧ 0）
	mint pochhammer(int x, int n) {
		// verify : https://atcoder.jp/contests/agc070/tasks/agc070_c

		int x2 = x + n - 1;
		if (x <= 0 && 0 <= x2) return 0;

		if (x > 0) {
			Assert(x2 <= n_max);
			return fac[x2] * fac_inv[x - 1];
		}
		else {
			Assert(-x <= n_max);
			return (n & 1 ? -1 : 1) * fac[-x] * fac_inv[-x2 - 1];
		}
	}

	// ポッホハマー記号の逆数 1/x^(n) を返す（n ≧ 0）
	mint pochhammer_inv(int x, int n) {
		// verify : https://atcoder.jp/contests/agc070/tasks/agc070_c

		int x2 = x + n - 1;
		Assert(!(x <= 0 && 0 <= x2));

		if (x > 0) {
			Assert(x2 <= n_max);
			return fac_inv[x2] * fac[x - 1];
		}
		else {
			Assert(-x <= n_max);
			return (n & 1 ? -1 : 1) * fac_inv[-x] * fac[-x2 - 1];
		}
	}
};


int main() {
//	input_from_file("input.txt");
//	output_to_file("output.txt");

	int n, K;
	cin >> n >> K;

	vl a(n), b(n);
	cin >> a >> b;

	Factorial_mint fm(n + 10);

	ll a_sum = accumulate(all(a), 0LL);
	ll b_sum = accumulate(all(b), 0LL);

	vm pow2(n + 1);
	pow2[0] = 1;
	rep(i, n) pow2[i + 1] = pow2[i] * 2;

	mint res = 0;

	repi(A, 1, K / 2) {
		int B = K - 2 * A;
		if (B >= n) continue;
		if (B < A) break;

		// n 本中 B 本を選んで A 個のブロックに分ける．
		mint cnt = fm.bin(B - 1, A - 1) * fm.bin(n - B - 1, A - 1);
		cnt *= 2 * pow2[A - 1] * fm.fact(A - 1);

		res += cnt * (mint(a_sum) * 2 * A + mint(b_sum) * B);
	}

	EXIT(res);
}
accuracy: 1
time_ms: 110
memory_kb: 30936
final_rank: 2

code_snippet: #ifndef HIDDEN_IN_VS // 折りたたみ用

// 警告の抑制
#define _CRT_SECURE_NO_WARNINGS

// ライブラリの読み込み
#include <bits/stdc++.h>
using namespace std;

// 型名の短縮
using ll = long long; using ull = unsigned long long; // -2^63 ～ 2^63 = 9e18（int は -2^31 ～ 2^31 = 2e9）
using pii = pair<int, int>;	using pll = pair<ll, ll>;	using pil = pair<int, ll>;	using pli = pair<ll, int>;
using vi = vector<int>;		using vvi = vector<vi>;		using vvvi = vector<vvi>;	using vvvvi = vector<vvvi>;
using vl = vector<ll>;		using vvl = vector<vl>;		using vvvl = vector<vvl>;	using vvvvl = vector<vvvl>;
using vb = vector<bool>;	using vvb = vector<vb>;		using vvvb = vector<vvb>;
using vc = vector<char>;	using vvc = vector<vc>;		using vvvc = vector<vvc>;
using vd = vector<double>;	using vvd = vector<vd>;		using vvvd = vector<vvd>;
template <class T> using priority_queue_rev = priority_queue<T, vector<T>, greater<T>>;
using Graph = vvi;

// 定数の定義
const double PI = acos(-1);
int DX[4] = { 1, 0, -1, 0 }; // 4 近傍（下，右，上，左）
int DY[4] = { 0, 1, 0, -1 };
int INF = 1001001001; ll INFL = 4004004003094073385LL; // (int)INFL = INF, (int)(-INFL) = -INF;

// 入出力高速化
struct fast_io { fast_io() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(18); } } fastIOtmp;

// 汎用マクロの定義
#define all(a) (a).begin(), (a).end()
#define sz(x) ((int)(x).size())
#define lbpos(a, x) (int)distance((a).begin(), std::lower_bound(all(a), (x)))
#define ubpos(a, x) (int)distance((a).begin(), std::upper_bound(all(a), (x)))
#define Yes(b) {cout << ((b) ? "Yes\n" : "No\n");}
#define rep(i, n) for(int i = 0, i##_len = int(n); i < i##_len; ++i) // 0 から n-1 まで昇順
#define repi(i, s, t) for(int i = int(s), i##_end = int(t); i <= i##_end; ++i) // s から t まで昇順
#define repir(i, s, t) for(int i = int(s), i##_end = int(t); i >= i##_end; --i) // s から t まで降順
#define repe(v, a) for(const auto& v : (a)) // a の全要素（変更不可能）
#define repea(v, a) for(auto& v : (a)) // a の全要素（変更可能）
#define repb(set, d) for(int set = 0, set##_ub = 1 << int(d); set < set##_ub; ++set) // d ビット全探索（昇順）
#define repis(i, set) for(int i = lsb(set), bset##i = set; i < 32; bset##i -= 1 << i, i = lsb(bset##i)) // set の全要素（昇順）
#define repp(a) sort(all(a)); for(bool a##_perm = true; a##_perm; a##_perm = next_permutation(all(a))) // a の順列全て（昇順）
#define uniq(a) {sort(all(a)); (a).erase(unique(all(a)), (a).end());} // 重複除去
#define EXIT(a) {cout << (a) << endl; exit(0);} // 強制終了
#define inQ(x, y, u, l, d, r) ((u) <= (x) && (l) <= (y) && (x) < (d) && (y) < (r)) // 半開矩形内判定

// 汎用関数の定義
template <class T> inline ll powi(T n, int k) { ll v = 1; rep(i, k) v *= n; return v; }
template <class T> inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; } // 最大値を更新（更新されたら true を返す）
template <class T> inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; } // 最小値を更新（更新されたら true を返す）
template <class T> inline T getb(T set, int i) { return (set >> i) & T(1); }
template <class T> inline T smod(T n, T m) { n %= m; if (n < 0) n += m; return n; } // 非負mod

// 演算子オーバーロード
template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template <class T> inline istream& operator>>(istream& is, vector<T>& v) { repea(x, v) is >> x; return is; }
template <class T> inline vector<T>& operator--(vector<T>& v) { repea(x, v) --x; return v; }
template <class T> inline vector<T>& operator++(vector<T>& v) { repea(x, v) ++x; return v; }

#endif // 折りたたみ用


#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;

#ifdef _MSC_VER
#include "localACL.hpp"
#endif

using mint = modint998244353;
//using mint = static_modint<(int)1e9+7>;
//using mint = modint; // mint::set_mod(m);

using vm = vector<mint>; using vvm = vector<vm>; using vvvm = vector<vvm>; using vvvvm = vector<vvvm>; using pim = pair<int, mint>;
#endif


#ifdef _MSC_VER // 手元環境（Visual Studio）
#include "local.hpp"
#else // 提出用（gcc）
int mute_dump = 0;
int frac_print = 0;
#if __has_include(<atcoder/all>)
namespace atcoder {
	inline istream& operator>>(istream& is, mint& x) { ll x_; is >> x_; x = x_; return is; }
	inline ostream& operator<<(ostream& os, const mint& x) { os << x.val(); return os; }
}
#endif
inline int popcount(int n) { return __builtin_popcount(n); }
inline int popcount(ll n) { return __builtin_popcountll(n); }
inline int lsb(int n) { return n != 0 ? __builtin_ctz(n) : 32; }
inline int lsb(ll n) { return n != 0 ? __builtin_ctzll(n) : 64; }
inline int msb(int n) { return n != 0 ? (31 - __builtin_clz(n)) : -1; }
inline int msb(ll n) { return n != 0 ? (63 - __builtin_clzll(n)) : -1; }
#define dump(...)
#define dumpel(v)
#define dump_math(v)
#define input_from_file(f)
#define output_to_file(f)
//#define Assert(b) { if (!(b)) { vc MLE(1<<30); EXIT(MLE.back()); } } // RE の代わりに MLE を出す
#endif

#define Assert(b) assert(b)

//【階乗など（法が大きな素数）】
/*
* Factorial_mint(int N) : O(n)
*	N まで計算可能として初期化する．
*
* mint fact(int n) : O(1)
*	n! を返す．
*
* mint fact_inv(int n) : O(1)
*	1/n! を返す（n が負なら 0 を返す）
*
* mint inv(int n) : O(1)
*	1/n を返す．
*
* mint perm(int n, int r) : O(1)
*	順列の数 nPr を返す．
*
* mint perm_inv(int n, int r) : O(1)
*	順列の数の逆数 1/nPr を返す．
*
* mint bin(int n, int r) : O(1)
*	二項係数 nCr を返す．
*
* mint bin_inv(int n, int r) : O(1)
*	二項係数の逆数 1/nCr を返す．
*
* mint mul(vi rs) : O(|rs|)
*	多項係数 nC[rs] を返す．（n = Σrs）
*
* mint hom(int n, int r) : O(1)
*	重複組合せの数 nHr = n+r-1Cr を返す（0H0 = 1 とする）
*
* mint neg_bin(int n, int r) : O(1)
*	負の二項係数 nCr = (-1)^r -n+r-1Cr を返す（n ≦ 0, r ≧ 0）
*
* mint pochhammer(int x, int n) : O(1)
*	ポッホハマー記号 x^(n) を返す（n ≧ 0）
*
* mint pochhammer_inv(int x, int n) : O(1)
*	ポッホハマー記号の逆数 1/x^(n) を返す（n ≧ 0）
*/
class Factorial_mint {
	int n_max;

	// 階乗と階乗の逆数の値を保持するテーブル
	vm fac, fac_inv;

public:
	// n! までの階乗とその逆数を前計算しておく．O(n)
	Factorial_mint(int n) : n_max(n), fac(n + 1), fac_inv(n + 1) {
		// verify : https://atcoder.jp/contests/dwacon6th-prelims/tasks/dwacon6th_prelims_b

		fac[0] = 1;
		repi(i, 1, n) fac[i] = fac[i - 1] * i;

		fac_inv[n] = fac[n].inv();
		repir(i, n - 1, 0) fac_inv[i] = fac_inv[i + 1] * (i + 1);
	}
	Factorial_mint() : n_max(0) {} // ダミー

	// n! を返す．
	mint fact(int n) const {
		// verify : https://atcoder.jp/contests/dwacon6th-prelims/tasks/dwacon6th_prelims_b

		Assert(0 <= n && n <= n_max);
		return fac[n];
	}

	// 1/n! を返す（n が負なら 0 を返す）
	mint fact_inv(int n) const {
		// verify : https://atcoder.jp/contests/abc289/tasks/abc289_h

		Assert(n <= n_max);
		if (n < 0) return 0;
		return fac_inv[n];
	}

	// 1/n を返す．
	mint inv(int n) const {
		// verify : https://atcoder.jp/contests/exawizards2019/tasks/exawizards2019_d

		Assert(n > 0);
		Assert(n <= n_max);
		return fac[n - 1] * fac_inv[n];
	}

	// 順列の数 nPr を返す．
	mint perm(int n, int r) const {
		// verify : https://atcoder.jp/contests/abc172/tasks/abc172_e

		Assert(n <= n_max);

		if (r < 0 || n - r < 0) return 0;
		return fac[n] * fac_inv[n - r];
	}

	// 順列の数 nPr の逆数を返す．
	mint perm_inv(int n, int r) const {
		// verify : https://yukicoder.me/problems/no/3139

		Assert(n <= n_max);
		Assert(0 <= r); Assert(r <= n);

		return fac_inv[n] * fac[n - r];
	}

	// 二項係数 nCr を返す．
	mint bin(int n, int r) const {
		// verify : https://judge.yosupo.jp/problem/binomial_coefficient_prime_mod

		Assert(n <= n_max);
		if (r < 0 || n - r < 0) return 0;
		return fac[n] * fac_inv[r] * fac_inv[n - r];
	}

	// 二項係数の逆数 1/nCr を返す．
	mint bin_inv(int n, int r) const {
		// verify : https://www.codechef.com/problems/RANDCOLORING

		Assert(n <= n_max);
		Assert(r >= 0);
		Assert(n - r >= 0);
		return fac_inv[n] * fac[r] * fac[n - r];
	}

	// 多項係数 nC[rs] を返す．
	mint mul(const vi& rs) const {
		// verify : https://yukicoder.me/problems/no/2141

		if (*min_element(all(rs)) < 0) return 0;
		int n = accumulate(all(rs), 0);
		Assert(n <= n_max);

		mint res = fac[n];
		repe(r, rs) res *= fac_inv[r];

		return res;
	}

	// 重複組合せの数 nHr = n+r-1Cr を返す（0H0 = 1 とする）
	mint hom(int n, int r) {
		// verify : https://mojacoder.app/users/riantkb/problems/toj_ex_2

		if (n == 0) return (int)(r == 0);
		if (r < 0 || n - 1 < 0) return 0;
		Assert(n + r - 1 <= n_max);
		return fac[n + r - 1] * fac_inv[r] * fac_inv[n - 1];
	}

	// 負の二項係数 nCr を返す（n ≦ 0, r ≧ 0）
	mint neg_bin(int n, int r) {
		// verify : https://atcoder.jp/contests/abc345/tasks/abc345_g

		if (n == 0) return (int)(r == 0);
		if (r < 0 || -n - 1 < 0) return 0;
		Assert(-n + r - 1 <= n_max);
		return (r & 1 ? -1 : 1) * fac[-n + r - 1] * fac_inv[r] * fac_inv[-n - 1];
	}

	// ポッホハマー記号 x^(n) を返す（n ≧ 0）
	mint pochhammer(int x, int n) {
		// verify : https://atcoder.jp/contests/agc070/tasks/agc070_c

		int x2 = x + n - 1;
		if (x <= 0 && 0 <= x2) return 0;

		if (x > 0) {
			Assert(x2 <= n_max);
			return fac[x2] * fac_inv[x - 1];
		}
		else {
			Assert(-x <= n_max);
			return (n & 1 ? -1 : 1) * fac[-x] * fac_inv[-x2 - 1];
		}
	}

	// ポッホハマー記号の逆数 1/x^(n) を返す（n ≧ 0）
	mint pochhammer_inv(int x, int n) {
		// verify : https://atcoder.jp/contests/agc070/tasks/agc070_c

		int x2 = x + n - 1;
		Assert(!(x <= 0 && 0 <= x2));

		if (x > 0) {
			Assert(x2 <= n_max);
			return fac_inv[x2] * fac[x - 1];
		}
		else {
			Assert(-x <= n_max);
			return (n & 1 ? -1 : 1) * fac_inv[-x] * fac[-x2 - 1];
		}
	}
};


int main() {
//	input_from_file("input.txt");
//	output_to_file("output.txt");

	int n, K;
	cin >> n >> K;

	vl a(n), b(n);
	cin >> a >> b;

	Factorial_mint fm(n + 10);

	ll a_sum = accumulate(all(a), 0LL);
	ll b_sum = accumulate(all(b), 0LL);

	vm pow2(n + 1);
	pow2[0] = 1;
	rep(i, n) pow2[i + 1] = pow2[i] * 2;

	mint res = 0;

	repi(A, 1, K / 2) {
		int B = K - 2 * A;
		if (B >= n) continue;
		if (B < A) break;

		// n 本中 B 本を選んで A 個のブロックに分ける．
		mint cnt = fm.bin(B - 1, A - 1) * fm.bin(n - B - 1, A - 1);
		cnt *= 2 * pow2[A - 1] * fm.fact(A - 1);

		res += cnt * (a_sum * 2 * A + b_sum * B);
	}

	EXIT(res);
}
accuracy: 0.4
time_ms: 70
memory_kb: 22352
final_rank: 11

code_snippet: #ifndef HIDDEN_IN_VS // 折りたたみ用

// 警告の抑制
#define _CRT_SECURE_NO_WARNINGS

// ライブラリの読み込み
#include <bits/stdc++.h>
using namespace std;

// 型名の短縮
using ll = long long; using ull = unsigned long long; // -2^63 ～ 2^63 = 9e18（int は -2^31 ～ 2^31 = 2e9）
using pii = pair<int, int>;	using pll = pair<ll, ll>;	using pil = pair<int, ll>;	using pli = pair<ll, int>;
using vi = vector<int>;		using vvi = vector<vi>;		using vvvi = vector<vvi>;	using vvvvi = vector<vvvi>;
using vl = vector<ll>;		using vvl = vector<vl>;		using vvvl = vector<vvl>;	using vvvvl = vector<vvvl>;
using vb = vector<bool>;	using vvb = vector<vb>;		using vvvb = vector<vvb>;
using vc = vector<char>;	using vvc = vector<vc>;		using vvvc = vector<vvc>;
using vd = vector<double>;	using vvd = vector<vd>;		using vvvd = vector<vvd>;
template <class T> using priority_queue_rev = priority_queue<T, vector<T>, greater<T>>;
using Graph = vvi;

// 定数の定義
const double PI = acos(-1);
int DX[4] = { 1, 0, -1, 0 }; // 4 近傍（下，右，上，左）
int DY[4] = { 0, 1, 0, -1 };
int INF = 1001001001; ll INFL = 4004004003094073385LL; // (int)INFL = INF, (int)(-INFL) = -INF;

// 入出力高速化
struct fast_io { fast_io() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(18); } } fastIOtmp;

// 汎用マクロの定義
#define all(a) (a).begin(), (a).end()
#define sz(x) ((int)(x).size())
#define lbpos(a, x) (int)distance((a).begin(), std::lower_bound(all(a), (x)))
#define ubpos(a, x) (int)distance((a).begin(), std::upper_bound(all(a), (x)))
#define Yes(b) {cout << ((b) ? "Yes\n" : "No\n");}
#define rep(i, n) for(int i = 0, i##_len = int(n); i < i##_len; ++i) // 0 から n-1 まで昇順
#define repi(i, s, t) for(int i = int(s), i##_end = int(t); i <= i##_end; ++i) // s から t まで昇順
#define repir(i, s, t) for(int i = int(s), i##_end = int(t); i >= i##_end; --i) // s から t まで降順
#define repe(v, a) for(const auto& v : (a)) // a の全要素（変更不可能）
#define repea(v, a) for(auto& v : (a)) // a の全要素（変更可能）
#define repb(set, d) for(int set = 0, set##_ub = 1 << int(d); set < set##_ub; ++set) // d ビット全探索（昇順）
#define repis(i, set) for(int i = lsb(set), bset##i = set; i < 32; bset##i -= 1 << i, i = lsb(bset##i)) // set の全要素（昇順）
#define repp(a) sort(all(a)); for(bool a##_perm = true; a##_perm; a##_perm = next_permutation(all(a))) // a の順列全て（昇順）
#define uniq(a) {sort(all(a)); (a).erase(unique(all(a)), (a).end());} // 重複除去
#define EXIT(a) {cout << (a) << endl; exit(0);} // 強制終了
#define inQ(x, y, u, l, d, r) ((u) <= (x) && (l) <= (y) && (x) < (d) && (y) < (r)) // 半開矩形内判定

// 汎用関数の定義
template <class T> inline ll powi(T n, int k) { ll v = 1; rep(i, k) v *= n; return v; }
template <class T> inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; } // 最大値を更新（更新されたら true を返す）
template <class T> inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; } // 最小値を更新（更新されたら true を返す）
template <class T> inline T getb(T set, int i) { return (set >> i) & T(1); }
template <class T> inline T smod(T n, T m) { n %= m; if (n < 0) n += m; return n; } // 非負mod

// 演算子オーバーロード
template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template <class T> inline istream& operator>>(istream& is, vector<T>& v) { repea(x, v) is >> x; return is; }
template <class T> inline vector<T>& operator--(vector<T>& v) { repea(x, v) --x; return v; }
template <class T> inline vector<T>& operator++(vector<T>& v) { repea(x, v) ++x; return v; }

#endif // 折りたたみ用


#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;

#ifdef _MSC_VER
#include "localACL.hpp"
#endif

using mint = modint998244353;
//using mint = static_modint<(int)1e9+7>;
//using mint = modint; // mint::set_mod(m);

using vm = vector<mint>; using vvm = vector<vm>; using vvvm = vector<vvm>; using vvvvm = vector<vvvm>; using pim = pair<int, mint>;
#endif


#ifdef _MSC_VER // 手元環境（Visual Studio）
#include "local.hpp"
#else // 提出用（gcc）
int mute_dump = 0;
int frac_print = 0;
#if __has_include(<atcoder/all>)
namespace atcoder {
	inline istream& operator>>(istream& is, mint& x) { ll x_; is >> x_; x = x_; return is; }
	inline ostream& operator<<(ostream& os, const mint& x) { os << x.val(); return os; }
}
#endif
inline int popcount(int n) { return __builtin_popcount(n); }
inline int popcount(ll n) { return __builtin_popcountll(n); }
inline int lsb(int n) { return n != 0 ? __builtin_ctz(n) : 32; }
inline int lsb(ll n) { return n != 0 ? __builtin_ctzll(n) : 64; }
inline int msb(int n) { return n != 0 ? (31 - __builtin_clz(n)) : -1; }
inline int msb(ll n) { return n != 0 ? (63 - __builtin_clzll(n)) : -1; }
#define dump(...)
#define dumpel(v)
#define dump_math(v)
#define input_from_file(f)
#define output_to_file(f)
#define Assert(b) { if (!(b)) { vc MLE(1<<30); EXIT(MLE.back()); } } // RE の代わりに MLE を出す
#endif


//【階乗など（法が大きな素数）】
/*
* Factorial_mint(int N) : O(n)
*	N まで計算可能として初期化する．
*
* mint fact(int n) : O(1)
*	n! を返す．
*
* mint fact_inv(int n) : O(1)
*	1/n! を返す（n が負なら 0 を返す）
*
* mint inv(int n) : O(1)
*	1/n を返す．
*
* mint perm(int n, int r) : O(1)
*	順列の数 nPr を返す．
*
* mint perm_inv(int n, int r) : O(1)
*	順列の数の逆数 1/nPr を返す．
*
* mint bin(int n, int r) : O(1)
*	二項係数 nCr を返す．
*
* mint bin_inv(int n, int r) : O(1)
*	二項係数の逆数 1/nCr を返す．
*
* mint mul(vi rs) : O(|rs|)
*	多項係数 nC[rs] を返す．（n = Σrs）
*
* mint hom(int n, int r) : O(1)
*	重複組合せの数 nHr = n+r-1Cr を返す（0H0 = 1 とする）
*
* mint neg_bin(int n, int r) : O(1)
*	負の二項係数 nCr = (-1)^r -n+r-1Cr を返す（n ≦ 0, r ≧ 0）
*
* mint pochhammer(int x, int n) : O(1)
*	ポッホハマー記号 x^(n) を返す（n ≧ 0）
*
* mint pochhammer_inv(int x, int n) : O(1)
*	ポッホハマー記号の逆数 1/x^(n) を返す（n ≧ 0）
*/
class Factorial_mint {
	int n_max;

	// 階乗と階乗の逆数の値を保持するテーブル
	vm fac, fac_inv;

public:
	// n! までの階乗とその逆数を前計算しておく．O(n)
	Factorial_mint(int n) : n_max(n), fac(n + 1), fac_inv(n + 1) {
		// verify : https://atcoder.jp/contests/dwacon6th-prelims/tasks/dwacon6th_prelims_b

		fac[0] = 1;
		repi(i, 1, n) fac[i] = fac[i - 1] * i;

		fac_inv[n] = fac[n].inv();
		repir(i, n - 1, 0) fac_inv[i] = fac_inv[i + 1] * (i + 1);
	}
	Factorial_mint() : n_max(0) {} // ダミー

	// n! を返す．
	mint fact(int n) const {
		// verify : https://atcoder.jp/contests/dwacon6th-prelims/tasks/dwacon6th_prelims_b

		Assert(0 <= n && n <= n_max);
		return fac[n];
	}

	// 1/n! を返す（n が負なら 0 を返す）
	mint fact_inv(int n) const {
		// verify : https://atcoder.jp/contests/abc289/tasks/abc289_h

		Assert(n <= n_max);
		if (n < 0) return 0;
		return fac_inv[n];
	}

	// 1/n を返す．
	mint inv(int n) const {
		// verify : https://atcoder.jp/contests/exawizards2019/tasks/exawizards2019_d

		Assert(n > 0);
		Assert(n <= n_max);
		return fac[n - 1] * fac_inv[n];
	}

	// 順列の数 nPr を返す．
	mint perm(int n, int r) const {
		// verify : https://atcoder.jp/contests/abc172/tasks/abc172_e

		Assert(n <= n_max);

		if (r < 0 || n - r < 0) return 0;
		return fac[n] * fac_inv[n - r];
	}

	// 順列の数 nPr の逆数を返す．
	mint perm_inv(int n, int r) const {
		// verify : https://yukicoder.me/problems/no/3139

		Assert(n <= n_max);
		Assert(0 <= r); Assert(r <= n);

		return fac_inv[n] * fac[n - r];
	}

	// 二項係数 nCr を返す．
	mint bin(int n, int r) const {
		// verify : https://judge.yosupo.jp/problem/binomial_coefficient_prime_mod

		Assert(n <= n_max);
		if (r < 0 || n - r < 0) return 0;
		return fac[n] * fac_inv[r] * fac_inv[n - r];
	}

	// 二項係数の逆数 1/nCr を返す．
	mint bin_inv(int n, int r) const {
		// verify : https://www.codechef.com/problems/RANDCOLORING

		Assert(n <= n_max);
		Assert(r >= 0);
		Assert(n - r >= 0);
		return fac_inv[n] * fac[r] * fac[n - r];
	}

	// 多項係数 nC[rs] を返す．
	mint mul(const vi& rs) const {
		// verify : https://yukicoder.me/problems/no/2141

		if (*min_element(all(rs)) < 0) return 0;
		int n = accumulate(all(rs), 0);
		Assert(n <= n_max);

		mint res = fac[n];
		repe(r, rs) res *= fac_inv[r];

		return res;
	}

	// 重複組合せの数 nHr = n+r-1Cr を返す（0H0 = 1 とする）
	mint hom(int n, int r) {
		// verify : https://mojacoder.app/users/riantkb/problems/toj_ex_2

		if (n == 0) return (int)(r == 0);
		if (r < 0 || n - 1 < 0) return 0;
		Assert(n + r - 1 <= n_max);
		return fac[n + r - 1] * fac_inv[r] * fac_inv[n - 1];
	}

	// 負の二項係数 nCr を返す（n ≦ 0, r ≧ 0）
	mint neg_bin(int n, int r) {
		// verify : https://atcoder.jp/contests/abc345/tasks/abc345_g

		if (n == 0) return (int)(r == 0);
		if (r < 0 || -n - 1 < 0) return 0;
		Assert(-n + r - 1 <= n_max);
		return (r & 1 ? -1 : 1) * fac[-n + r - 1] * fac_inv[r] * fac_inv[-n - 1];
	}

	// ポッホハマー記号 x^(n) を返す（n ≧ 0）
	mint pochhammer(int x, int n) {
		// verify : https://atcoder.jp/contests/agc070/tasks/agc070_c

		int x2 = x + n - 1;
		if (x <= 0 && 0 <= x2) return 0;

		if (x > 0) {
			Assert(x2 <= n_max);
			return fac[x2] * fac_inv[x - 1];
		}
		else {
			Assert(-x <= n_max);
			return (n & 1 ? -1 : 1) * fac[-x] * fac_inv[-x2 - 1];
		}
	}

	// ポッホハマー記号の逆数 1/x^(n) を返す（n ≧ 0）
	mint pochhammer_inv(int x, int n) {
		// verify : https://atcoder.jp/contests/agc070/tasks/agc070_c

		int x2 = x + n - 1;
		Assert(!(x <= 0 && 0 <= x2));

		if (x > 0) {
			Assert(x2 <= n_max);
			return fac_inv[x2] * fac[x - 1];
		}
		else {
			Assert(-x <= n_max);
			return (n & 1 ? -1 : 1) * fac_inv[-x] * fac[-x2 - 1];
		}
	}
};


int main() {
//	input_from_file("input.txt");
//	output_to_file("output.txt");

	int n, K;
	cin >> n >> K;

	vl a(n), b(n);
	cin >> a >> b;

	Factorial_mint fm(n + 10);

	ll a_sum = accumulate(all(a), 0LL);
	ll b_sum = accumulate(all(b), 0LL);

	vm pow2(n + 1);
	pow2[0] = 1;
	rep(i, n) pow2[i + 1] = pow2[i] * 2;

	mint res = 0;

	repi(A, 1, K / 2) {
		int B = K - 2 * A;
		if (B >= n) continue;
		if (B < A) break;

		// n 本中 B 本を選んで A 個のブロックに分ける．
		mint cnt = fm.bin(B - 1, A - 1) * fm.bin(n - B - 1, A - 1);
		cnt *= 2 * pow2[A - 1] * fm.fact(A - 1);

		res += cnt * (a_sum * 2 * A + b_sum * B);
	}

	EXIT(res);
}
accuracy: 0.4
time_ms: 70
memory_kb: 22352
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=9167167167167167167;
const int INF=100000000;
const ll mod=998244353;
#define rep(i,a) for (ll i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}

namespace po167{
struct combination{
	int upper;
	long long MOD;
	std::vector<long long> fact;
	std::vector<long long> rev;
	std::vector<long long> fact_rev;
	combination(int max,long long mod):upper(max),MOD(mod),fact(max+1),rev(max+1),fact_rev(max+1){
		for(long long i=0;i<=max;i++){
			if(i<2){
				fact[i]=1;
				fact_rev[i]=1;
				rev[i]=1;
				continue;
			}
			fact[i]=(fact[i-1]*i)%mod;
			rev[i]=mod-((mod/i)*rev[mod%i])%mod;
			fact_rev[i]=(fact_rev[i-1]*rev[i])%mod;
		}
	}
	long long Comb(int x,int y){
		assert(upper>=x);
		if (x<y||y<0||x<0) return 0;
		return (((fact_rev[y]*fact_rev[x-y])%MOD)*fact[x])%MOD;
	}
	long long P(int x,int y){
		assert(upper>=x);
		if (x<y||y<0||x<0) return 0;
		return (fact_rev[x-y]*fact[x])%MOD;
	}
};
}
using po167::combination;

ll jyo(ll x,ll y,ll z){
  ll H=y; //ここから
       ll a=1,b=(x%z+z)%z,c=1;
       while(H>0){
         a*=2;
         if(H%a!=0){
           H-=a/2;
           c*=b;
           c%=z;
         }
        b*=b;
         b%=z;
      } //ここまで
 return c;
}



void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t=1;
	//cin>>t;
	rep(i,t) solve();
}

void solve(){
	ll n,k;
	cin>>n>>k;
	ll A=0,B=0;
	rep(i,n){
		ll a;
		cin>>a;
		A+=a;
	}rep(i,n){
		ll a;
		cin>>a;
		B+=a;
	}
	A%=mod,B%=mod;
	combination table(n,mod);
	ll ans=0;
	for(ll i=1;i<=n;i++){
		ll tmp=(jyo(2,i,mod)*table.fact[i-1])%mod;
		ll C=k-i*2;
		if(C<i||n-C<i) continue;
		tmp=(tmp*table.Comb(n-C-1,i-1))%mod;
		tmp=(tmp*table.Comb(C-1,i-1))%mod;
		ans=(ans+(tmp*((i*2*A+B*C)%mod))%mod)%mod;
	}
	cout<<ans<<"\n";
}
accuracy: 1
time_ms: 320
memory_kb: 26560
final_rank: 3

code_snippet: #include <bits/stdc++.h>



#include <utility>

namespace atcoder {

namespace internal {

// @param m `1 <= m`
// @return x mod m
constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

// Fast moduler by barrett reduction
// Reference: https://en.wikipedia.org/wiki/Barrett_reduction
// NOTE: reconsider after Ice Lake
struct barrett {
    unsigned int _m;
    unsigned long long im;

    // @param m `1 <= m`
    barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    // @return m
    unsigned int umod() const { return _m; }

    // @param a `0 <= a < m`
    // @param b `0 <= b < m`
    // @return `a * b % m`
    unsigned int mul(unsigned int a, unsigned int b) const {
        // [1] m = 1
        // a = b = im = 0, so okay

        // [2] m >= 2
        // im = ceil(2^64 / m)
        // -> im * m = 2^64 + r (0 <= r < m)
        // let z = a*b = c*m + d (0 <= c, d < m)
        // a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im
        // c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2
        // ((ab * im) >> 64) == c or c + 1
        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

// @param n `0 <= n`
// @param m `1 <= m`
// @return `(x ** n) % m`
constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

// Reference:
// M. Forisek and J. Jancina,
// Fast Primality Testing for Integers That Fit into a Machine Word
// @param n `0 <= n`
constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    for (long long a : {2, 7, 61}) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

// @param b `1 <= b`
// @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    // Contracts:
    // [1] s - m0 * a = 0 (mod b)
    // [2] t - m1 * a = 0 (mod b)
    // [3] s * |m1| + t * |m0| <= b
    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b

        // [3]:
        // (s - t * u) * |m1| + t * |m0 - m1 * u|
        // <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)
        // = s * |m1| + t * |m0| <= b

        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    // by [3]: |m0| <= b/g
    // by g != b: |m0| < b/g
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

// Compile time primitive root
// @param m must be prime
// @return primitive root (and minimum in now)
constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

}  // namespace internal

}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }
    static_modint(bool v) { _v = ((unsigned int)(v) % umod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }
    dynamic_modint(bool v) { _v = ((unsigned int)(v) % mod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder

#define For(i, a, b) for (int(i) = (int)(a); (i) < (int)(b); ++(i))
#define rFor(i, a, b) for (int(i) = (int)(a)-1; (i) >= (int)(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<lint, lint> pll;
template <class T>
bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T>
bool chmin(T &a, const T &b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T>
T div_floor(T a, T b) {
    if (b < 0) a *= -1, b *= -1;
    return a >= 0 ? a / b : (a + 1) / b - 1;
}
template <class T>
T div_ceil(T a, T b) {
    if (b < 0) a *= -1, b *= -1;
    return a > 0 ? (a - 1) / b + 1 : a / b;
}

constexpr lint mod = 1000000007;
constexpr lint INF = mod * mod;
constexpr int MAX = 200010;

using namespace atcoder;
using mint = modint998244353;

vector<mint> fact;
vector<mint> revfact;

void setfact(int n) {
    fact.resize(n + 1);
    revfact.resize(n + 1);
    fact[0] = 1;
    rep(i, n) fact[i + 1] = fact[i] * mint(i + 1);

    revfact[n] = fact[n].inv();
    for (int i = n - 1; i >= 0; i--) revfact[i] = revfact[i + 1] * mint(i + 1);
}

mint getC(int n, int r) {
    if (n < r || r < 0) return 0;
    return fact[n] * revfact[r] * revfact[n - r];
}

int main() {
    int n, K;
    scanf("%d%d", &n, &K);
    mint side = 0, bottom = 0;
    rep(i, n) {
        int a;
        scanf("%d", &a);
        side += a;
    }
    rep(i, n) {
        int a;
        scanf("%d", &a);
        bottom += a;
    }

    setfact(2 * n);
    mint pow2 = 1, a = 0, b = 0;
    for (int l = 0; 2 * l < K; ++l) {
        mint c = fact[l - 1] * pow2 * getC(K - 2 * l - 1, l - 1) *
                 getC(n - K + 2 * l - 1, l - 1);
        a += c * 2 * l;
        b += c * (K - 2 * l);
        pow2 *= 2;
    }
    printf("%u\n", (side * a + bottom * b).val());
}
accuracy: 1
time_ms: 150
memory_kb: 18804
final_rank: 1

code_snippet: #include <bits/stdc++.h>



#include <utility>

namespace atcoder {

namespace internal {

// @param m `1 <= m`
// @return x mod m
constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

// Fast moduler by barrett reduction
// Reference: https://en.wikipedia.org/wiki/Barrett_reduction
// NOTE: reconsider after Ice Lake
struct barrett {
    unsigned int _m;
    unsigned long long im;

    // @param m `1 <= m`
    barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    // @return m
    unsigned int umod() const { return _m; }

    // @param a `0 <= a < m`
    // @param b `0 <= b < m`
    // @return `a * b % m`
    unsigned int mul(unsigned int a, unsigned int b) const {
        // [1] m = 1
        // a = b = im = 0, so okay

        // [2] m >= 2
        // im = ceil(2^64 / m)
        // -> im * m = 2^64 + r (0 <= r < m)
        // let z = a*b = c*m + d (0 <= c, d < m)
        // a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im
        // c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2
        // ((ab * im) >> 64) == c or c + 1
        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

// @param n `0 <= n`
// @param m `1 <= m`
// @return `(x ** n) % m`
constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

// Reference:
// M. Forisek and J. Jancina,
// Fast Primality Testing for Integers That Fit into a Machine Word
// @param n `0 <= n`
constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    for (long long a : {2, 7, 61}) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

// @param b `1 <= b`
// @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    // Contracts:
    // [1] s - m0 * a = 0 (mod b)
    // [2] t - m1 * a = 0 (mod b)
    // [3] s * |m1| + t * |m0| <= b
    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b

        // [3]:
        // (s - t * u) * |m1| + t * |m0 - m1 * u|
        // <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)
        // = s * |m1| + t * |m0| <= b

        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    // by [3]: |m0| <= b/g
    // by g != b: |m0| < b/g
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

// Compile time primitive root
// @param m must be prime
// @return primitive root (and minimum in now)
constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

}  // namespace internal

}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }
    static_modint(bool v) { _v = ((unsigned int)(v) % umod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }
    dynamic_modint(bool v) { _v = ((unsigned int)(v) % mod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder

#define For(i, a, b) for (int(i) = (int)(a); (i) < (int)(b); ++(i))
#define rFor(i, a, b) for (int(i) = (int)(a)-1; (i) >= (int)(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<lint, lint> pll;
template <class T>
bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T>
bool chmin(T &a, const T &b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T>
T div_floor(T a, T b) {
    if (b < 0) a *= -1, b *= -1;
    return a >= 0 ? a / b : (a + 1) / b - 1;
}
template <class T>
T div_ceil(T a, T b) {
    if (b < 0) a *= -1, b *= -1;
    return a > 0 ? (a - 1) / b + 1 : a / b;
}

constexpr lint mod = 1000000007;
constexpr lint INF = mod * mod;
constexpr int MAX = 200010;

using namespace atcoder;
using mint = modint998244353;

vector<mint> fact;
vector<mint> revfact;

void setfact(int n) {
    fact.resize(n + 1);
    revfact.resize(n + 1);
    fact[0] = 1;
    rep(i, n) fact[i + 1] = fact[i] * mint(i + 1);

    revfact[n] = fact[n].inv();
    for (int i = n - 1; i >= 0; i--) revfact[i] = revfact[i + 1] * mint(i + 1);
}

mint getC(int n, int r) {
    if (n < r || r < 0) return 0;
    return fact[n] * revfact[r] * revfact[n - r];
}

int main() {
    int n, K;
    scanf("%d%d", &n, &K);
    mint side = 0, bottom = 0;
    rep(i, n) {
        int a;
        scanf("%d", &a);
        side += a;
    }
    rep(i, n) {
        int a;
        scanf("%d", &a);
        bottom += a;
    }

    setfact(n);
    mint pow2 = 1, a = 0, b = 0;
    for (int l = 0; 2 * l < K; ++l) {
        mint c = fact[l - 1] * pow2 * getC(K - 2 * l - 1, l - 1) *
                 getC(n - K + 2 * l - 1, l - 1);
        a += c * 2 * l;
        b += c * (K - 2 * l);
        pow2 *= 2;
    }
    printf("%u\n", (side * a + bottom * b).val());
}
accuracy: 0.8
time_ms: 140
memory_kb: 10808
final_rank: 9

code_snippet: #include <bits/stdc++.h>

#include<bits/stdc++.h>

namespace ProconLib{

    template<typename MInt>
    class ModCombination{
        int N;
        std::vector<MInt> fact;
        std::vector<MInt> factInv;
        public:
        ModCombination(int n);
        MInt F(int n){return fact[n];}
        MInt FI(int n){return factInv[n];}
        MInt P(int n,int k){return fact[n]*factInv[n-k];}
        MInt PI(int n,int k){return factInv[n]*fact[n-k];}
        MInt C(int n,int k){return fact[n]*factInv[k]*factInv[n-k];}
        MInt CI(int n,int k){return factInv[n]*fact[k]*fact[n-k];}
    };

    template<typename MInt>
    ModCombination<MInt>::ModCombination(int n):N(n),fact(n+1),factInv(n+1){
        fact[0]=MInt(1);
        for(int i=1;i<=n;i++) fact[i]=fact[i-1]*MInt(i);
        factInv[n]=inv(fact[n]);
        for(int i=n-1;i>=0;i--){
            factInv[i]=factInv[i+1]*MInt(i+1);
        }
    }
    
}
#include<iostream>

namespace ProconLib{
    using ll=long long;
    using Int=int;
    template<Int MOD,bool IsPrime=true>
    class ModInt{
        Int n;        
        static Int regularize(int n){Int tmp=n%MOD; return tmp>=0 ? tmp : tmp+MOD;}
        static Int regularize(ll n){Int tmp=n%MOD; return tmp>=0 ? tmp : tmp+MOD;}
        public:
        ModInt():n(0){};
        ModInt(int n):n(regularize(n)){}
        ModInt(long long n):n(regularize(n)){}
        ModInt(const ModInt<MOD,IsPrime> &mn):n(mn.n){}
        explicit operator int() const{return n;}
        explicit operator long long() const{return n;}

        ModInt<MOD,IsPrime>& operator+=(ModInt<MOD,IsPrime> rhs);
        ModInt<MOD,IsPrime>& operator-=(ModInt<MOD,IsPrime> rhs);
        ModInt<MOD,IsPrime>& operator*=(ModInt<MOD,IsPrime> rhs);

        bool operator==(ModInt<MOD,IsPrime> rhs){return n==rhs.n;}
        const Int& get() const {return n;}
        void set(int x){n=regularize(x);}
        void set(ll x){n=regularize(x);}        
    };

    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator+(ModInt<MOD,IsPrime> lhs,ModInt<MOD,IsPrime> rhs){return lhs+=rhs;};
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator+(ModInt<MOD,IsPrime> lhs,int rhs){return lhs+ModInt<MOD,IsPrime>(rhs);}
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator+(ModInt<MOD,IsPrime> lhs,ll rhs){return lhs+ModInt<MOD,IsPrime>(rhs);}
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator+(int lhs,ModInt<MOD,IsPrime> rhs){return ModInt<MOD,IsPrime>(lhs)+rhs;}
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator+(ll lhs,ModInt<MOD,IsPrime> rhs){return ModInt<MOD,IsPrime>(lhs)+rhs;}

    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator+(ModInt<MOD,IsPrime> mn){return mn;};
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator-(ModInt<MOD,IsPrime> mn){return ModInt<MOD,IsPrime>(-mn.get());};

    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator-(ModInt<MOD,IsPrime> lhs,ModInt<MOD,IsPrime> rhs){return lhs-=rhs;};
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator-(ModInt<MOD,IsPrime> lhs,int rhs){return lhs-ModInt<MOD,IsPrime>(rhs);};
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator-(ModInt<MOD,IsPrime> lhs,ll rhs){return lhs-ModInt<MOD,IsPrime>(rhs);};
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator-(int lhs,ModInt<MOD,IsPrime> rhs){return ModInt<MOD,IsPrime>(lhs)-rhs;};
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator-(ll lhs,ModInt<MOD,IsPrime> rhs){return ModInt<MOD,IsPrime>(lhs)-rhs;};

    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator*(ModInt<MOD,IsPrime> lhs,ModInt<MOD,IsPrime> rhs){return lhs*=rhs;};
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator*(ModInt<MOD,IsPrime> lhs,int rhs){return lhs*ModInt<MOD,IsPrime>(rhs);}
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator*(ModInt<MOD,IsPrime> lhs,ll rhs){return lhs*ModInt<MOD,IsPrime>(rhs);}
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator*(ll lhs,ModInt<MOD,IsPrime> rhs){return ModInt<MOD,IsPrime>(lhs)*rhs;}
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> operator*(int lhs,ModInt<MOD,IsPrime> rhs){return ModInt<MOD,IsPrime>(lhs)*rhs;}

    template<Int MOD>
    ModInt<MOD,true> operator/(ModInt<MOD,true> lhs,ModInt<MOD,true> rhs);
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> powm(ModInt<MOD,IsPrime> x,Int k);
    template<Int MOD>
    ModInt<MOD,true> inv(ModInt<MOD,true> x){return powm(x,MOD-2);}

    template<Int MOD,bool IsPrime>
    std::ostream& operator<<(std::ostream& os,const ModInt<MOD,IsPrime> &mn);
    

    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime>& ModInt<MOD,IsPrime>::operator+=(ModInt<MOD,IsPrime> rhs){
        n+=rhs.n;
        n= n>=MOD ? n-MOD : n;
        return *this;
    }
    
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime>& ModInt<MOD,IsPrime>::operator-=(ModInt rhs){
        n=n-rhs.n<0 ? n-rhs.n+MOD : n-rhs.n;
        return *this;
    }
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime>& ModInt<MOD,IsPrime>::operator*=(ModInt<MOD,IsPrime> rhs){
        n=ll(n)*rhs.n%MOD;
        return *this;
    }
    
    template<Int MOD>
    ModInt<MOD,true> operator/(ModInt<MOD,true> lhs,ModInt<MOD,true> rhs){
        return lhs*inv(rhs);
    }
    template<Int MOD,bool IsPrime>
    ModInt<MOD,IsPrime> powm(ModInt<MOD,IsPrime> x,Int k){
        ModInt<MOD,IsPrime> res(1);
        while(k){
            if(k&1) res*=x;
            k>>=1;
            x*=x;
        }
        return res;
    }

    template<Int MOD,bool IsPrime>
    std::ostream& operator<<(std::ostream& os,const ModInt<MOD,IsPrime> &mn){
        os<<mn.get();
        return os;
    }

    template<Int MOD,bool IsPrime>
    std::istream& operator>>(std::istream& is,ModInt<MOD,IsPrime> &mn){
        Int tmp;
        is>>tmp;
        mn.set(tmp);
        return is;
    }
}

using namespace std;

using ll = long long;
const ll MOD = 998244353;
using mInt = ProconLib::ModInt<MOD, true>;
const int MAX_N = 4000000;
ProconLib::ModCombination<mInt> mComb(MAX_N);

mInt fact(ll x) { return mComb.F(x); }
mInt calc(ll n, ll k) {
  if (n == 0 && k == 0) return 1;
  if (k <= 0) return 0;
  if (n<0) return 0;
  return mComb.C(n + k - 1, k - 1);
}

int main() {
  ll n, k;
  cin >> n >> k;

  vector<int> a(n);
  vector<int> b(n);
  for (int i = 0; i < n; i++) cin >> a[i];
  for (int i = 0; i < n; i++) cin >> b[i];

  mInt P = 0;
  for (int i = 1; i <= n; i++) {
    mInt x = mInt(k - 2 * i) * mInt(2) * mInt(n);
    mInt y = mInt(powm(mInt(2), i - 1)) * fact(i - 1);
    mInt z = calc(k - 2 * i - i, i) * calc(n - (k - 2 * i) - i, i);
    // cerr << "#P " << i << " " << x << " " << y << " " << z << endl;
    P += x * y * z;
  }
  P = P / mInt(n);
  // cerr << P << endl;

  mInt Q = 0;
  for (int i = 1; i <= n; i++) {
    mInt x = mInt(2) * mInt(i) * mInt(2) * mInt(n);
    mInt y = powm(mInt(2), i - 1) * fact(i - 1);
    mInt z = calc(k - 2 * i - i, i) * calc(n - (k - 2 * i) - i, i);
    // cerr << "#Q " << i << " " << x << " " << y << " " << z << endl;
    Q += x * y * z;
  }
  Q = Q / mInt(n);

  mInt asum = accumulate(a.begin(), a.end(), 0LL);
  mInt bsum = accumulate(b.begin(), b.end(), 0LL);
  mInt ans = bsum * P + asum * Q;
  cout << ans << endl;

  return 0;
}
accuracy: 1
time_ms: 610
memory_kb: 42136
final_rank: 5

code_snippet: #include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <algorithm>
#include <queue>
#include <stack>
#include <functional>
#include <bitset>
#include <assert.h>
#include <unordered_map>
#include <fstream>
#include <ctime>
#include <complex>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1<<30;
const ll linf = 1LL<<62;
const int MAX = 2020000;
ll dy[8] = {1,-1,0,0,1,-1,1,-1};
ll dx[8] = {0,0,1,-1,1,-1,-1,1};
const double pi = acos(-1);
const double eps = 1e-10;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << "debug: " << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << "debug: " << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//const int mod = 1e9 + 7;
const int mod = 998244353;

template <std::uint_fast64_t Modulus> class modint {
  using u64 = std::uint_fast64_t;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
	return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
	return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
	return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
	return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
	a += rhs.a;
	if (a >= Modulus) {
	  a -= Modulus;
	}
	return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
	if (a < rhs.a) {
	  a += Modulus;
	}
	a -= rhs.a;
	return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
	a = a * rhs.a % Modulus;
	return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
	u64 exp = Modulus - 2;
	while (exp) {
	  if (exp % 2) {
		*this *= rhs;
	  }
	  rhs *= rhs;
	  exp /= 2;
	}
	return *this;
  }
};

using mint = modint<mod>;

vector<ll> fac(MAX), finv(MAX), inv(MAX);

void comInit(){
	fac[0] = fac[1] = 1;
	finv[0] = finv[1] = 1;
	inv[1] = 1;
	for(ll i=2; i<MAX; i++){
		fac[i] = fac[i-1]*i % mod;
		inv[i] = mod - inv[mod%i] * (mod/i) % mod;
		finv[i] = finv[i-1] * inv[i] % mod;
	}
}


ll com(ll n, ll k){
	if(n < k) return 0;
	if(n < 0 || k < 0) return 0;
	return fac[n] * (finv[k] * finv[n-k] % mod) % mod;
}

ll modpow(ll x, ll n, ll mod){
	ll res = 1;
	while(n > 0){
		if(n & 1) res = res * x % mod;
		x = x * x % mod;
		n >>= 1;
	}
	return res;
}

int main(){
	ll n,k; cin >> n >> k;
	mint suma = 0, sumb = 0;
	vl a(n); rep(i,n) cin >> a[i], suma += a[i];
	vl b(n); rep(i,n) cin >> b[i], sumb += b[i];
	comInit();
	mint ans = 0;
	for(int t=1; t*3<=k; t++){
		mint tmp = modpow(2,t,mod);
		tmp = tmp * fac[t-1] * com(k-t*2-1,t-1) * com(n+t*2-k-1,t-1);
		ans += suma * tmp * t * 2 + sumb * tmp * (k-2*t);
	}
	cout << ans.value() << "\n";
}
accuracy: 1
time_ms: 670
memory_kb: 65920
final_rank: 7

code_snippet: #include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <algorithm>
#include <queue>
#include <stack>
#include <functional>
#include <bitset>
#include <assert.h>
#include <unordered_map>
#include <fstream>
#include <ctime>
#include <complex>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1<<30;
const ll linf = 1LL<<62;
const int MAX = 2020000;
ll dy[8] = {1,-1,0,0,1,-1,1,-1};
ll dx[8] = {0,0,1,-1,1,-1,-1,1};
const double pi = acos(-1);
const double eps = 1e-10;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << "debug: " << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << "debug: " << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//const int mod = 1e9 + 7;
const int mod = 998244353;

template <std::uint_fast64_t Modulus> class modint {
  using u64 = std::uint_fast64_t;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
	return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
	return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
	return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
	return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
	a += rhs.a;
	if (a >= Modulus) {
	  a -= Modulus;
	}
	return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
	if (a < rhs.a) {
	  a += Modulus;
	}
	a -= rhs.a;
	return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
	a = a * rhs.a % Modulus;
	return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
	u64 exp = Modulus - 2;
	while (exp) {
	  if (exp % 2) {
		*this *= rhs;
	  }
	  rhs *= rhs;
	  exp /= 2;
	}
	return *this;
  }
};

using mint = modint<mod>;

vector<ll> fac(MAX), finv(MAX), inv(MAX);

void comInit(){
	fac[0] = fac[1] = 1;
	finv[0] = finv[1] = 1;
	inv[1] = 1;
	for(ll i=2; i<MAX; i++){
		fac[i] = fac[i-1]*i % mod;
		inv[i] = mod - inv[mod%i] * (mod/i) % mod;
		finv[i] = finv[i-1] * inv[i] % mod;
	}
}


ll com(ll n, ll k){
	if(n < k) return 0;
	if(n < 0 || k < 0) return 0;
	return fac[n] * (finv[k] * finv[n-k] % mod) % mod;
}

ll modpow(ll x, ll n, ll mod){
	ll res = 1;
	while(n > 0){
		if(n & 1) res = res * x % mod;
		x = x * x % mod;
		n >>= 1;
	}
	return res;
}

int main(){
	ll n,k; cin >> n >> k;
	mint suma = 0, sumb = 0;
	vl a(n); rep(i,n) cin >> a[i], suma += a[i];
	vl b(n); rep(i,n) cin >> b[i], sumb += b[i];
	comInit();
	mint ans = 0;
	for(int t=0; t*3<=k-3; t++){
		if(n-2+t < k-3) continue;
		ll rest = k-3 - t*3;
		ans += (suma * (t+1) * 4 + sumb * (rest+t+1) * 2) * com(t+rest,rest) * modpow(2,t,mod);
	}
	cout << ans.value() << "\n";
}
accuracy: 0.1
time_ms: 50
memory_kb: 49872
final_rank: 16

code_snippet: #include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
// #include <atcoder/all>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define ALL(v) v.begin(),v.end()
template < class T > inline bool chmax(T& a, T b) {if (a < b) { a=b; return true; } return false; }
template < class T > inline bool chmin(T& a, T b) {if (a > b) { a=b; return true; } return false; }
#define DEBUG_VLL(vec) for(int sz=0;sz<int(vec.size());sz++) std::cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

const long long MOD = 998244353;
const long long HIGHINF = (long long)1e18;
const int INF = (int)1e9;

class ModInt {
public:
    long long x;
    constexpr ModInt(const long long x=0) : x((x+MOD)%MOD) {}
    constexpr ModInt& operator+=(const ModInt rhs) {
        x += rhs.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }
    constexpr ModInt operator+(const ModInt rhs) const {
        return ModInt(*this) += rhs; 
    }
    constexpr ModInt& operator-=(const ModInt& rhs) {
        x -= rhs.x;
        if (x < 0) x += MOD;
        return *this;
    }
    constexpr ModInt operator-(const ModInt rhs) const {
        return ModInt(*this) -= rhs; 
    }
    constexpr ModInt& operator*=(const ModInt& rhs) {
        x = x * rhs.x % MOD;
        return *this;
    }
    constexpr ModInt operator*(const ModInt rhs) const {
        return ModInt(*this) *= rhs; 
    }
    constexpr ModInt& operator/=(const ModInt& rhs) {
        ModInt div = powmod(rhs, MOD - 2);
        (x *= div.x) %= MOD;
        return *this;
    }
    constexpr ModInt operator/(const ModInt rhs) const {
        return ModInt(*this) /= rhs;
    }
    constexpr ModInt powmod(ModInt m, long long p) {
        if (p == 0) return ModInt(1);
        ModInt tmp = powmod(m, p / 2);
        if (p & 1) return tmp * tmp * m;
        else return tmp * tmp;
    }
    constexpr ModInt& operator++() {
        x += 1;
        return *this;
    }
    constexpr ModInt operator++(int) {
        ModInt tmp(*this);
        operator++();
        return tmp;
    }
    constexpr ModInt& operator--() {
        x -= 1;
        return *this;
    }
    constexpr ModInt operator--(int) {
        ModInt tmp(*this);
        operator--();
        return tmp;
    }

    friend ostream& operator<<(ostream& os, const ModInt &rhs) {
        os << rhs.x;
        return os;
    }
    friend istream& operator>>(istream& is, ModInt& rhs) {
        is >> rhs.x;
        return is;
    }
};
bool operator==(const ModInt& lhs, const ModInt& rhs) {
    return lhs.x == rhs.x;
}
bool operator!=(const ModInt& lhs, const ModInt& rhs) {
    return !(lhs == rhs);
}
ModInt powmod(ModInt m, long long p) {
    if (p == 0) return ModInt(1);
    ModInt tmp = powmod(m, p / 2);
    if (p & 1) return tmp * tmp * m;
    else return tmp * tmp;
}

using modi = ModInt;


// [ModInt]
// verified at https://atcoder.jp/contests/abc021/submissions/15053490
const int NMAX = 2000005;
template < typename T >
class Combination {
public:
    std::vector<T> fac, invfac;
    Combination() {
        fac.resize(NMAX), invfac.resize(NMAX);
        fac[0] = fac[1] = T(1);
        invfac[0] = invfac[1] = T(1);
        for (int i = 2; i <= NMAX; i++) {
            fac[i] = fac[i - 1] * T(i);
            invfac[i] = invfac[i - 1] * powmod(T(i), MOD - 2);
        }
    }

    // nCr = n! / r!(n-r)!
    T nCr(int n, int r) {
        if (n < 0 || r > n || r < 0) return T(0);
        return fac[n] * invfac[r] * invfac[n - r];
    }
    
    // 重複組み合わせ nHr = (n + r - 1)C(r)
    T nHr(int n, int r) {
        return nCr(n + r - 1, r);
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, k; cin >> n >> k;
    Combination<modi> comb;

    modi asum = 0, bsum = 0;
    for (int i = 0; i < n; i++) {
        ll a; cin >> a; asum += modi(a);
    }
    for (int i = 0; i < n; i++) {
        ll b; cin >> b; bsum += modi(b);
    }
    V<modi> fac(n + 1, 1), pow2(n + 1, 1);
    pow2[1] = modi(2);
    for (int i = 2; i < n; i++) {
        fac[i] = fac[i - 1] * modi(i);
        pow2[i] = pow2[i - 1] * modi(2);
    }

    modi ans = 0;
    for (int cyc = 1; 2 * cyc <= k; cyc++) {
        modi tmp = pow2[cyc] * fac[cyc - 1] * comb.nHr(cyc, k - 3 * cyc) * comb.nHr(cyc, n - k + cyc);
        ans += tmp * (modi(2 * cyc) * asum + modi(k - 2 * cyc) * bsum);
    }
    cout << ans << '\n';
    return 0;
}
accuracy: 1
time_ms: 500
memory_kb: 50096
final_rank: 4

code_snippet: #include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
// #include <atcoder/all>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define ALL(v) v.begin(),v.end()
template < class T > inline bool chmax(T& a, T b) {if (a < b) { a=b; return true; } return false; }
template < class T > inline bool chmin(T& a, T b) {if (a > b) { a=b; return true; } return false; }
#define DEBUG_VLL(vec) for(int sz=0;sz<int(vec.size());sz++) std::cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

const long long MOD = 998244353;
const long long HIGHINF = (long long)1e18;
const int INF = (int)1e9;

class ModInt {
public:
    long long x;
    constexpr ModInt(const long long x=0) : x((x+MOD)%MOD) {}
    constexpr ModInt& operator+=(const ModInt rhs) {
        x += rhs.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }
    constexpr ModInt operator+(const ModInt rhs) const {
        return ModInt(*this) += rhs; 
    }
    constexpr ModInt& operator-=(const ModInt& rhs) {
        x -= rhs.x;
        if (x < 0) x += MOD;
        return *this;
    }
    constexpr ModInt operator-(const ModInt rhs) const {
        return ModInt(*this) -= rhs; 
    }
    constexpr ModInt& operator*=(const ModInt& rhs) {
        x = x * rhs.x % MOD;
        return *this;
    }
    constexpr ModInt operator*(const ModInt rhs) const {
        return ModInt(*this) *= rhs; 
    }
    constexpr ModInt& operator/=(const ModInt& rhs) {
        ModInt div = powmod(rhs, MOD - 2);
        (x *= div.x) %= MOD;
        return *this;
    }
    constexpr ModInt operator/(const ModInt rhs) const {
        return ModInt(*this) /= rhs;
    }
    constexpr ModInt powmod(ModInt m, long long p) {
        if (p == 0) return ModInt(1);
        ModInt tmp = powmod(m, p / 2);
        if (p & 1) return tmp * tmp * m;
        else return tmp * tmp;
    }
    constexpr ModInt& operator++() {
        x += 1;
        return *this;
    }
    constexpr ModInt operator++(int) {
        ModInt tmp(*this);
        operator++();
        return tmp;
    }
    constexpr ModInt& operator--() {
        x -= 1;
        return *this;
    }
    constexpr ModInt operator--(int) {
        ModInt tmp(*this);
        operator--();
        return tmp;
    }

    friend ostream& operator<<(ostream& os, const ModInt &rhs) {
        os << rhs.x;
        return os;
    }
    friend istream& operator>>(istream& is, ModInt& rhs) {
        is >> rhs.x;
        return is;
    }
};
bool operator==(const ModInt& lhs, const ModInt& rhs) {
    return lhs.x == rhs.x;
}
bool operator!=(const ModInt& lhs, const ModInt& rhs) {
    return !(lhs == rhs);
}
ModInt powmod(ModInt m, long long p) {
    if (p == 0) return ModInt(1);
    ModInt tmp = powmod(m, p / 2);
    if (p & 1) return tmp * tmp * m;
    else return tmp * tmp;
}

using modi = ModInt;


// [ModInt]
// verified at https://atcoder.jp/contests/abc021/submissions/15053490
const int NMAX = 5000005;
template < typename T >
class Combination {
public:
    std::vector<T> fac, invfac;
    Combination() {
        fac.resize(NMAX), invfac.resize(NMAX);
        fac[0] = fac[1] = T(1);
        invfac[0] = invfac[1] = T(1);
        for (int i = 2; i <= NMAX; i++) {
            fac[i] = fac[i - 1] * T(i);
            invfac[i] = invfac[i - 1] * powmod(T(i), MOD - 2);
        }
    }

    // nCr = n! / r!(n-r)!
    T nCr(int n, int r) {
        if (n < 0 || r > n || r < 0) return T(0);
        return fac[n] * invfac[r] * invfac[n - r];
    }
    
    // 重複組み合わせ nHr = (n + r - 1)C(r)
    T nHr(int n, int r) {
        return nCr(n + r - 1, r);
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, k; cin >> n >> k;
    Combination<modi> comb;

    modi asum = 0, bsum = 0;
    for (int i = 0; i < n; i++) {
        ll a, b; cin >> a >> b;
        asum += modi(a), bsum += modi(b);
    }
    V<modi> fac(n + 1, 1), pow2(n + 1, 1);
    pow2[1] = modi(2);
    for (int i = 2; i <= n; i++) {
        fac[i] = fac[i - 1] * modi(i);
        pow2[i] = pow2[i - 1] * modi(2);
    }

    modi ans = 0;
    for (int cyc = 1; 2 * cyc <= k; cyc++) {
        modi tmp = pow2[cyc] * fac[cyc - 1] * comb.nCr(k - 2 * cyc - 1, k - 3 * cyc) * comb.nCr(n - k + 2 * cyc - 1, n - k + cyc);
        ans += tmp * (modi(2 * cyc) * asum + modi(k - 2 * cyc) * bsum);
    }
    cout << ans << '\n';
    return 0;
}
accuracy: 0.1
time_ms: 910
memory_kb: 81176
final_rank: 20

code_snippet: #include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
// #include <atcoder/all>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define ALL(v) v.begin(),v.end()
template < class T > inline bool chmax(T& a, T b) {if (a < b) { a=b; return true; } return false; }
template < class T > inline bool chmin(T& a, T b) {if (a > b) { a=b; return true; } return false; }
#define DEBUG_VLL(vec) for(int sz=0;sz<int(vec.size());sz++) std::cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

const long long MOD = 998244353;
const long long HIGHINF = (long long)1e18;
const int INF = (int)1e9;

class ModInt {
public:
    long long x;
    constexpr ModInt(const long long x=0) : x((x+MOD)%MOD) {}
    constexpr ModInt& operator+=(const ModInt rhs) {
        x += rhs.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }
    constexpr ModInt operator+(const ModInt rhs) const {
        return ModInt(*this) += rhs; 
    }
    constexpr ModInt& operator-=(const ModInt& rhs) {
        x -= rhs.x;
        if (x < 0) x += MOD;
        return *this;
    }
    constexpr ModInt operator-(const ModInt rhs) const {
        return ModInt(*this) -= rhs; 
    }
    constexpr ModInt& operator*=(const ModInt& rhs) {
        x = x * rhs.x % MOD;
        return *this;
    }
    constexpr ModInt operator*(const ModInt rhs) const {
        return ModInt(*this) *= rhs; 
    }
    constexpr ModInt& operator/=(const ModInt& rhs) {
        ModInt div = powmod(rhs, MOD - 2);
        (x *= div.x) %= MOD;
        return *this;
    }
    constexpr ModInt operator/(const ModInt rhs) const {
        return ModInt(*this) /= rhs;
    }
    constexpr ModInt powmod(ModInt m, long long p) {
        if (p == 0) return ModInt(1);
        ModInt tmp = powmod(m, p / 2);
        if (p & 1) return tmp * tmp * m;
        else return tmp * tmp;
    }
    constexpr ModInt& operator++() {
        x += 1;
        return *this;
    }
    constexpr ModInt operator++(int) {
        ModInt tmp(*this);
        operator++();
        return tmp;
    }
    constexpr ModInt& operator--() {
        x -= 1;
        return *this;
    }
    constexpr ModInt operator--(int) {
        ModInt tmp(*this);
        operator--();
        return tmp;
    }

    friend ostream& operator<<(ostream& os, const ModInt &rhs) {
        os << rhs.x;
        return os;
    }
    friend istream& operator>>(istream& is, ModInt& rhs) {
        is >> rhs.x;
        return is;
    }
};
bool operator==(const ModInt& lhs, const ModInt& rhs) {
    return lhs.x == rhs.x;
}
bool operator!=(const ModInt& lhs, const ModInt& rhs) {
    return !(lhs == rhs);
}
ModInt powmod(ModInt m, long long p) {
    if (p == 0) return ModInt(1);
    ModInt tmp = powmod(m, p / 2);
    if (p & 1) return tmp * tmp * m;
    else return tmp * tmp;
}

using modi = ModInt;


// [ModInt]
// verified at https://atcoder.jp/contests/abc021/submissions/15053490
const int NMAX = 5000005;
template < typename T >
class Combination {
public:
    std::vector<T> fac, invfac;
    Combination() {
        fac.resize(NMAX), invfac.resize(NMAX);
        fac[0] = fac[1] = T(1);
        invfac[0] = invfac[1] = T(1);
        for (int i = 2; i <= NMAX; i++) {
            fac[i] = fac[i - 1] * T(i);
            invfac[i] = invfac[i - 1] * powmod(T(i), MOD - 2);
        }
    }

    // nCr = n! / r!(n-r)!
    T nCr(int n, int r) {
        if (n < 0 || r > n || r < 0) return T(0);
        return fac[n] * invfac[r] * invfac[n - r];
    }
    
    // 重複組み合わせ nHr = (n + r - 1)C(r - 1)
    T nHr(int n, int r) {
        return nCr(n + r - 1, r);
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, k; cin >> n >> k;
    Combination<modi> comb;

    modi asum = 0, bsum = 0;
    for (int i = 0; i < n; i++) {
        modi a, b; cin >> a >> b;
        asum += modi(a), bsum += modi(b);
    }
    asum /= modi(n), bsum /= modi(n);
    V<modi> fac(n, 1), pow2(n, 1);
    pow2[1] = 2;
    for (int i = 2; i < n; i++) {
        fac[i] = fac[i - 1] * modi(i);
        pow2[i] = pow2[i - 1] * modi(2);
    }

    modi ans = 0;
    for (int cyc = 1; 2 * cyc <= k; cyc++) {
        modi tmp = pow2[cyc] * fac[cyc - 1] * modi(n) * comb.nHr(cyc, k - 3 * cyc) * comb.nHr(cyc, n - k + cyc);
        ans += tmp * (modi(2 * cyc) * asum + modi(k - 2 * cyc) * bsum);
    }
    cout << ans << '\n';
    return 0;
}
accuracy: 0.1
time_ms: 910
memory_kb: 81148
final_rank: 19

code_snippet: #include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
// #include <atcoder/all>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define ALL(v) v.begin(),v.end()
template < class T > inline bool chmax(T& a, T b) {if (a < b) { a=b; return true; } return false; }
template < class T > inline bool chmin(T& a, T b) {if (a > b) { a=b; return true; } return false; }
#define DEBUG_VLL(vec) for(int sz=0;sz<int(vec.size());sz++) std::cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

const long long MOD = 998244353;
const long long HIGHINF = (long long)1e18;
const int INF = (int)1e9;

class ModInt {
public:
    long long x;
    constexpr ModInt(const long long x=0) : x((x+MOD)%MOD) {}
    constexpr ModInt& operator+=(const ModInt rhs) {
        x += rhs.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }
    constexpr ModInt operator+(const ModInt rhs) const {
        return ModInt(*this) += rhs; 
    }
    constexpr ModInt& operator-=(const ModInt& rhs) {
        x -= rhs.x;
        if (x < 0) x += MOD;
        return *this;
    }
    constexpr ModInt operator-(const ModInt rhs) const {
        return ModInt(*this) -= rhs; 
    }
    constexpr ModInt& operator*=(const ModInt& rhs) {
        x = x * rhs.x % MOD;
        return *this;
    }
    constexpr ModInt operator*(const ModInt rhs) const {
        return ModInt(*this) *= rhs; 
    }
    constexpr ModInt& operator/=(const ModInt& rhs) {
        ModInt div = powmod(rhs, MOD - 2);
        (x *= div.x) %= MOD;
        return *this;
    }
    constexpr ModInt operator/(const ModInt rhs) const {
        return ModInt(*this) /= rhs;
    }
    constexpr ModInt powmod(ModInt m, long long p) {
        if (p == 0) return ModInt(1);
        ModInt tmp = powmod(m, p / 2);
        if (p & 1) return tmp * tmp * m;
        else return tmp * tmp;
    }
    constexpr ModInt& operator++() {
        x += 1;
        return *this;
    }
    constexpr ModInt operator++(int) {
        ModInt tmp(*this);
        operator++();
        return tmp;
    }
    constexpr ModInt& operator--() {
        x -= 1;
        return *this;
    }
    constexpr ModInt operator--(int) {
        ModInt tmp(*this);
        operator--();
        return tmp;
    }

    friend ostream& operator<<(ostream& os, const ModInt &rhs) {
        os << rhs.x;
        return os;
    }
    friend istream& operator>>(istream& is, ModInt& rhs) {
        is >> rhs.x;
        return is;
    }
};
bool operator==(const ModInt& lhs, const ModInt& rhs) {
    return lhs.x == rhs.x;
}
bool operator!=(const ModInt& lhs, const ModInt& rhs) {
    return !(lhs == rhs);
}
ModInt powmod(ModInt m, long long p) {
    if (p == 0) return ModInt(1);
    ModInt tmp = powmod(m, p / 2);
    if (p & 1) return tmp * tmp * m;
    else return tmp * tmp;
}

using modi = ModInt;


// [ModInt]
// verified at https://atcoder.jp/contests/abc021/submissions/15053490
const int NMAX = 1000005;
template < typename T >
class Combination {
public:
    std::vector<T> fac, invfac;
    Combination() {
        fac.resize(NMAX), invfac.resize(NMAX);
        fac[0] = fac[1] = T(1);
        invfac[0] = invfac[1] = T(1);
        for (int i = 2; i <= NMAX; i++) {
            fac[i] = fac[i - 1] * T(i);
            invfac[i] = invfac[i - 1] * powmod(T(i), MOD - 2);
        }
    }

    // nCr = n! / r!(n-r)!
    T nCr(int n, int r) {
        if (n < 0 || r > n || r < 0) return T(0);
        return fac[n] * invfac[r] * invfac[n - r];
    }
    
    // 重複組み合わせ nHr = (n + r - 1)C(r - 1)
    T nHr(int n, int r) {
        return nCr(n + r - 1, r);
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, k; cin >> n >> k;
    Combination<modi> comb;

    modi asum = 0, bsum = 0;
    for (int i = 0; i < n; i++) {
        modi a, b; cin >> a >> b;
        asum += modi(a), bsum += modi(b);
    }
    asum /= modi(n), bsum /= modi(n);
    V<modi> fac(n, 1), pow2(n, 1);
    pow2[1] = 2;
    for (int i = 2; i < n; i++) {
        fac[i] = fac[i - 1] * modi(i);
        pow2[i] = pow2[i - 1] * modi(2);
    }

    modi ans = 0;
    for (int cyc = 1; 2 * cyc <= k; cyc++) {
        modi tmp = pow2[cyc] * fac[cyc - 1] * modi(n) * comb.nHr(cyc, k - 3 * cyc) * comb.nHr(cyc, n - k + cyc);
        ans += tmp * (modi(2 * cyc) * asum + modi(k - 2 * cyc) * bsum);
    }
    cout << ans << '\n';
    return 0;
}
accuracy: 0.1
time_ms: 180
memory_kb: 18772
final_rank: 15

code_snippet: #include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
// #include <atcoder/all>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define ALL(v) v.begin(),v.end()
template < class T > inline bool chmax(T& a, T b) {if (a < b) { a=b; return true; } return false; }
template < class T > inline bool chmin(T& a, T b) {if (a > b) { a=b; return true; } return false; }
#define DEBUG_VLL(vec) for(int sz=0;sz<int(vec.size());sz++) std::cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

const long long MOD = 998244353;
const long long HIGHINF = (long long)1e18;
const int INF = (int)1e9;

class ModInt {
public:
    long long x;
    constexpr ModInt(const long long x=0) : x((x+MOD)%MOD) {}
    constexpr ModInt& operator+=(const ModInt rhs) {
        x += rhs.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }
    constexpr ModInt operator+(const ModInt rhs) const {
        return ModInt(*this) += rhs; 
    }
    constexpr ModInt& operator-=(const ModInt& rhs) {
        x -= rhs.x;
        if (x < 0) x += MOD;
        return *this;
    }
    constexpr ModInt operator-(const ModInt rhs) const {
        return ModInt(*this) -= rhs; 
    }
    constexpr ModInt& operator*=(const ModInt& rhs) {
        x = x * rhs.x % MOD;
        return *this;
    }
    constexpr ModInt operator*(const ModInt rhs) const {
        return ModInt(*this) *= rhs; 
    }
    constexpr ModInt& operator/=(const ModInt& rhs) {
        ModInt div = powmod(rhs, MOD - 2);
        (x *= div.x) %= MOD;
        return *this;
    }
    constexpr ModInt operator/(const ModInt rhs) const {
        return ModInt(*this) /= rhs;
    }
    constexpr ModInt powmod(ModInt m, long long p) {
        if (p == 0) return ModInt(1);
        ModInt tmp = powmod(m, p / 2);
        if (p & 1) return tmp * tmp * m;
        else return tmp * tmp;
    }
    constexpr ModInt& operator++() {
        x += 1;
        return *this;
    }
    constexpr ModInt operator++(int) {
        ModInt tmp(*this);
        operator++();
        return tmp;
    }
    constexpr ModInt& operator--() {
        x -= 1;
        return *this;
    }
    constexpr ModInt operator--(int) {
        ModInt tmp(*this);
        operator--();
        return tmp;
    }

    friend ostream& operator<<(ostream& os, const ModInt &rhs) {
        os << rhs.x;
        return os;
    }
    friend istream& operator>>(istream& is, ModInt& rhs) {
        is >> rhs.x;
        return is;
    }
};
bool operator==(const ModInt& lhs, const ModInt& rhs) {
    return lhs.x == rhs.x;
}
bool operator!=(const ModInt& lhs, const ModInt& rhs) {
    return !(lhs == rhs);
}
ModInt powmod(ModInt m, long long p) {
    if (p == 0) return ModInt(1);
    ModInt tmp = powmod(m, p / 2);
    if (p & 1) return tmp * tmp * m;
    else return tmp * tmp;
}

using modi = ModInt;


// [ModInt]
// verified at https://atcoder.jp/contests/abc021/submissions/15053490
const int NMAX = 1000005;
template < typename T >
class Combination {
public:
    std::vector<T> fac, invfac;
    Combination() {
        fac.resize(NMAX), invfac.resize(NMAX);
        fac[0] = fac[1] = T(1);
        invfac[0] = invfac[1] = T(1);
        for (int i = 2; i <= NMAX; i++) {
            fac[i] = fac[i - 1] * T(i);
            invfac[i] = invfac[i - 1] * powmod(T(i), MOD - 2);
        }
    }

    // nCr = n! / r!(n-r)!
    T nCr(int n, int r) {
        if (n < 0 || r > n || r < 0) return T(0);
        return fac[n] * invfac[r] * invfac[n - r];
    }
    
    // 重複組み合わせ nHr = (n + r - 1)C(r - 1)
    T nHr(int n, int r) {
        return nCr(n + r - 1, r);
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, k; cin >> n >> k;
    Combination<modi> comb;

    modi asum = 0, bsum = 0;
    for (int i = 0; i < n; i++) {
        modi a, b; cin >> a >> b;
        asum += a, bsum += b;
    }
    asum /= modi(n), bsum /= modi(n);
    V<modi> fac(n, 1), pow2(n, 1);
    pow2[1] = 2;
    for (int i = 2; i < n; i++) {
        fac[i] = fac[i - 1] * modi(i);
        pow2[i] = pow2[i - 1] * modi(2);
    }

    modi ans = 0;
    for (int cyc = 1; cyc < n; cyc++) {
        if (k < 2 * cyc) break;
        modi tmp = pow2[cyc] * fac[cyc - 1] * modi(n) * comb.nHr(cyc, k - 3 * cyc) * comb.nHr(cyc, n - k + cyc);
        ans += tmp * (modi(2 * cyc) * asum + modi(k - 2 * cyc) * bsum);
    }
    cout << ans << '\n';
    return 0;
}
accuracy: 0.1
time_ms: 180
memory_kb: 18700
final_rank: 13

code_snippet: #include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
// #include <atcoder/all>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define ALL(v) v.begin(),v.end()
template < class T > inline bool chmax(T& a, T b) {if (a < b) { a=b; return true; } return false; }
template < class T > inline bool chmin(T& a, T b) {if (a > b) { a=b; return true; } return false; }
#define DEBUG_VLL(vec) for(int sz=0;sz<int(vec.size());sz++) std::cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

const long long MOD = 998244353;
const long long HIGHINF = (long long)1e18;
const int INF = (int)1e9;

class ModInt {
public:
    long long x;
    constexpr ModInt(const long long x=0) : x((x+MOD)%MOD) {}
    constexpr ModInt& operator+=(const ModInt rhs) {
        x += rhs.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }
    constexpr ModInt operator+(const ModInt rhs) const {
        return ModInt(*this) += rhs; 
    }
    constexpr ModInt& operator-=(const ModInt& rhs) {
        x -= rhs.x;
        if (x < 0) x += MOD;
        return *this;
    }
    constexpr ModInt operator-(const ModInt rhs) const {
        return ModInt(*this) -= rhs; 
    }
    constexpr ModInt& operator*=(const ModInt& rhs) {
        x = x * rhs.x % MOD;
        return *this;
    }
    constexpr ModInt operator*(const ModInt rhs) const {
        return ModInt(*this) *= rhs; 
    }
    constexpr ModInt& operator/=(const ModInt& rhs) {
        ModInt div = powmod(rhs, MOD - 2);
        (x *= div.x) %= MOD;
        return *this;
    }
    constexpr ModInt operator/(const ModInt rhs) const {
        return ModInt(*this) /= rhs;
    }
    constexpr ModInt powmod(ModInt m, long long p) {
        if (p == 0) return ModInt(1);
        ModInt tmp = powmod(m, p / 2);
        if (p & 1) return tmp * tmp * m;
        else return tmp * tmp;
    }
    constexpr ModInt& operator++() {
        x += 1;
        return *this;
    }
    constexpr ModInt operator++(int) {
        ModInt tmp(*this);
        operator++();
        return tmp;
    }
    constexpr ModInt& operator--() {
        x -= 1;
        return *this;
    }
    constexpr ModInt operator--(int) {
        ModInt tmp(*this);
        operator--();
        return tmp;
    }

    friend ostream& operator<<(ostream& os, const ModInt &rhs) {
        os << rhs.x;
        return os;
    }
    friend istream& operator>>(istream& is, ModInt& rhs) {
        is >> rhs.x;
        return is;
    }
};
bool operator==(const ModInt& lhs, const ModInt& rhs) {
    return lhs.x == rhs.x;
}
bool operator!=(const ModInt& lhs, const ModInt& rhs) {
    return !(lhs == rhs);
}
ModInt powmod(ModInt m, long long p) {
    if (p == 0) return ModInt(1);
    ModInt tmp = powmod(m, p / 2);
    if (p & 1) return tmp * tmp * m;
    else return tmp * tmp;
}

using modi = ModInt;


// [ModInt]
// verified at https://atcoder.jp/contests/abc021/submissions/15053490
const int NMAX = 1000005;
template < typename T >
class Combination {
public:
    std::vector<T> fac, invfac;
    Combination() {
        fac.resize(NMAX), invfac.resize(NMAX);
        fac[0] = fac[1] = T(1);
        invfac[0] = invfac[1] = T(1);
        for (int i = 2; i <= NMAX; i++) {
            fac[i] = fac[i - 1] * T(i);
            invfac[i] = invfac[i - 1] * powmod(T(i), MOD - 2);
        }
    }

    // nCr = n! / r!(n-r)!
    T nCr(int n, int r) {
        if (n < 0 || r > n || r < 0) return T(0);
        return fac[n] * invfac[r] * invfac[n - r];
    }
    
    // 重複組み合わせ nHr = (n + r - 1)C(r - 1)
    T nHr(int n, int r) {
        return nCr(n + r - 1, r);
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, k; cin >> n >> k;
    Combination<modi> comb;

    modi asum = 0, bsum = 0;
    for (int i = 0; i < n; i++) {
        modi a, b; cin >> a >> b;
        asum += a, bsum += b;
    }
    asum /= modi(n), bsum /= modi(n);
    V<modi> fac(n, 1), pow2(n, 1);
    pow2[1] = 2;
    for (int i = 2; i < n; i++) {
        fac[i] = fac[i - 1] * modi(i);
        pow2[i] = pow2[i - 1] * modi(2);
    }

    modi ans = 0;
    for (int cyc = 1; cyc < n; cyc++) {
        if (k - 2 * cyc <= 0) break;
        modi tmp = pow2[cyc] * fac[cyc - 1] * modi(n) * comb.nHr(cyc, k - 3 * cyc) * comb.nHr(cyc, n - k + cyc);
        ans += tmp * (modi(2 * cyc) * asum + modi(k - 2 * cyc) * bsum);
    }
    cout << ans << '\n';
    return 0;
}
accuracy: 0.1
time_ms: 180
memory_kb: 18740
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T> ostream& operator << (ostream &s, set<T> P)
{ for(auto it : P) { s << "<" << it << "> "; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P)
{ for(auto it : P) { s << "<" << it.first << "->" << it.second << "> "; } return s << endl; }



// modint: mod 計算を int を扱うように扱える構造体
template<int MOD> struct Fp {
    long long val;
    constexpr Fp(long long v = 0) noexcept : val(v % MOD) {
        if (val < 0) val += MOD;
    }
    constexpr int getmod() { return MOD; }
    constexpr Fp operator - () const noexcept {
        return val ? MOD - val : 0;
    }
    constexpr Fp operator + (const Fp& r) const noexcept { return Fp(*this) += r; }
    constexpr Fp operator - (const Fp& r) const noexcept { return Fp(*this) -= r; }
    constexpr Fp operator * (const Fp& r) const noexcept { return Fp(*this) *= r; }
    constexpr Fp operator / (const Fp& r) const noexcept { return Fp(*this) /= r; }
    constexpr Fp& operator += (const Fp& r) noexcept {
        val += r.val;
        if (val >= MOD) val -= MOD;
        return *this;
    }
    constexpr Fp& operator -= (const Fp& r) noexcept {
        val -= r.val;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr Fp& operator *= (const Fp& r) noexcept {
        val = val * r.val % MOD;
        return *this;
    }
    constexpr Fp& operator /= (const Fp& r) noexcept {
        long long a = r.val, b = MOD, u = 1, v = 0;
        while (b) {
            long long t = a / b;
            a -= t * b; swap(a, b);
            u -= t * v; swap(u, v);
        }
        val = val * u % MOD;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr bool operator == (const Fp& r) const noexcept {
        return this->val == r.val;
    }
    constexpr bool operator != (const Fp& r) const noexcept {
        return this->val != r.val;
    }
    friend constexpr ostream& operator << (ostream &os, const Fp<MOD>& x) noexcept {
        return os << x.val;
    }
    friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept {
        if (n == 0) return 1;
        auto t = modpow(a, n / 2);
        t = t * t;
        if (n & 1) t = t * a;
        return t;
    }
};

// 二項係数ライブラリ
template<class T> struct BiCoef {
    vector<T> fact_, inv_, finv_;
    constexpr BiCoef() {}
    constexpr BiCoef(int n) noexcept : fact_(n, 1), inv_(n, 1), finv_(n, 1) {
        init(n);
    }
    constexpr void init(int n) noexcept {
        fact_.assign(n, 1), inv_.assign(n, 1), finv_.assign(n, 1);
        int MOD = fact_[0].getmod();
        for(int i = 2; i < n; i++){
            fact_[i] = fact_[i-1] * i;
            inv_[i] = -inv_[MOD%i] * (MOD/i);
            finv_[i] = finv_[i-1] * inv_[i];
        }
    }
    constexpr T com(int n, int k) const noexcept {
        if (n < k || n < 0 || k < 0) return 0;
        return fact_[n] * finv_[k] * finv_[n-k];
    }
    constexpr T fact(int n) const noexcept {
        if (n < 0) return 0;
        return fact_[n];
    }
    constexpr T inv(int n) const noexcept {
        if (n < 0) return 0;
        return inv_[n];
    }
    constexpr T finv(int n) const noexcept {
        if (n < 0) return 0;
        return finv_[n];
    }
};

const int MOD = 998244353;
using mint = Fp<MOD>;

int main() {
    int N, K;
    cin >> N >> K;
    BiCoef<mint> bc(N*2 + 1);
    mint A = 0, B = 0;
    for (int i = 0; i < N; ++i) { long long v; cin >> v; A += v; }
    for (int i = 0; i < N; ++i) { long long v; cin >> v; B += v; }
    vector<mint> two(N+5, 1);
    for (int i = 1; i < two.size(); ++i) two[i] = two[i-1] * 2;

    mint res = 0;
    for (int i = 1; i*2 <= K; ++i) {
        mint fac = bc.com(K - i*2 - 1, i - 1) *
                   bc.com(N - K + i*2 - 1, i - 1) *
                   bc.fact(i - 1) * two[i];
        mint tmp = fac * (A * i*2 + B * (K - i*2));
        res += tmp;
    }
    cout << res << endl;
}
accuracy: 1
time_ms: 680
memory_kb: 57388
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T> ostream& operator << (ostream &s, set<T> P)
{ for(auto it : P) { s << "<" << it << "> "; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P)
{ for(auto it : P) { s << "<" << it.first << "->" << it.second << "> "; } return s << endl; }



// modint: mod 計算を int を扱うように扱える構造体
template<int MOD> struct Fp {
    long long val;
    constexpr Fp(long long v = 0) noexcept : val(v % MOD) {
        if (val < 0) val += MOD;
    }
    constexpr int getmod() { return MOD; }
    constexpr Fp operator - () const noexcept {
        return val ? MOD - val : 0;
    }
    constexpr Fp operator + (const Fp& r) const noexcept { return Fp(*this) += r; }
    constexpr Fp operator - (const Fp& r) const noexcept { return Fp(*this) -= r; }
    constexpr Fp operator * (const Fp& r) const noexcept { return Fp(*this) *= r; }
    constexpr Fp operator / (const Fp& r) const noexcept { return Fp(*this) /= r; }
    constexpr Fp& operator += (const Fp& r) noexcept {
        val += r.val;
        if (val >= MOD) val -= MOD;
        return *this;
    }
    constexpr Fp& operator -= (const Fp& r) noexcept {
        val -= r.val;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr Fp& operator *= (const Fp& r) noexcept {
        val = val * r.val % MOD;
        return *this;
    }
    constexpr Fp& operator /= (const Fp& r) noexcept {
        long long a = r.val, b = MOD, u = 1, v = 0;
        while (b) {
            long long t = a / b;
            a -= t * b; swap(a, b);
            u -= t * v; swap(u, v);
        }
        val = val * u % MOD;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr bool operator == (const Fp& r) const noexcept {
        return this->val == r.val;
    }
    constexpr bool operator != (const Fp& r) const noexcept {
        return this->val != r.val;
    }
    friend constexpr ostream& operator << (ostream &os, const Fp<MOD>& x) noexcept {
        return os << x.val;
    }
    friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept {
        if (n == 0) return 1;
        auto t = modpow(a, n / 2);
        t = t * t;
        if (n & 1) t = t * a;
        return t;
    }
};

// 二項係数ライブラリ
template<class T> struct BiCoef {
    vector<T> fact_, inv_, finv_;
    constexpr BiCoef() {}
    constexpr BiCoef(int n) noexcept : fact_(n, 1), inv_(n, 1), finv_(n, 1) {
        init(n);
    }
    constexpr void init(int n) noexcept {
        fact_.assign(n, 1), inv_.assign(n, 1), finv_.assign(n, 1);
        int MOD = fact_[0].getmod();
        for(int i = 2; i < n; i++){
            fact_[i] = fact_[i-1] * i;
            inv_[i] = -inv_[MOD%i] * (MOD/i);
            finv_[i] = finv_[i-1] * inv_[i];
        }
    }
    constexpr T com(int n, int k) const noexcept {
        if (n < k || n < 0 || k < 0) return 0;
        return fact_[n] * finv_[k] * finv_[n-k];
    }
    constexpr T fact(int n) const noexcept {
        if (n < 0) return 0;
        return fact_[n];
    }
    constexpr T inv(int n) const noexcept {
        if (n < 0) return 0;
        return inv_[n];
    }
    constexpr T finv(int n) const noexcept {
        if (n < 0) return 0;
        return finv_[n];
    }
};

const int MOD = 998244353;
using mint = Fp<MOD>;

int main() {
    int N, K;
    cin >> N >> K;
    BiCoef<mint> bc(N+1);
    mint A = 0, B = 0;
    for (int i = 0; i < N; ++i) { long long v; cin >> v; A += v; }
    for (int i = 0; i < N; ++i) { long long v; cin >> v; B += v; }
    vector<mint> two(N+5, 1);
    for (int i = 1; i < two.size(); ++i) two[i] = two[i-1] * 2;

    mint res = 0;
    for (int i = 1; i*2 <= K; ++i) {
        mint fac = bc.com(K - i*2 - 1, i - 1) *
                   bc.com(N - K + i*2 - 1, i - 1) *
                   bc.fact(i - 1) * two[i];
        mint tmp = fac * (A * i*2 + B * (K - i*2));
        res += tmp;
    }
    cout << res << endl;
}
accuracy: 0.8
time_ms: 570
memory_kb: 33892
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int long long
const int MOD=998244353;

int pw(int n,int k){
  assert(k>=0);
  int res=1;
  while(k){
    if(k&1)(res*=n)%=MOD;
    (n*=n)%=MOD;
    k>>=1;
  }
  return res;
}
std::vector<int> Factorial(5e6),Finverse(5e6);
inline void Cinit(){
  Factorial[0]=1;
  for(int i=1;i<5e6;i++)Factorial[i]=(Factorial[i-1]*i)%MOD;
  Finverse[4999999]=pw(Factorial[4999999],MOD-2);
  for(int i=4999998;i>=0;i--)Finverse[i]=(i+1)*Finverse[i+1]%MOD;
}
int nCk(int n,int k){
  assert(n>=k&&k>=0);
  if(n<k)return 0;if(k<0)return 0;
  assert(n<5000000&&k<5000000);
  if(!Factorial[0])Cinit();
  int res=Factorial[n];
  (res*=Finverse[k])%=MOD;
  (res*=Finverse[n-k])%=MOD;
  return res;
}

signed main(){
  int n,k;cin>>n>>k;
  int asum=0,bsum=0;
  for(int i=0;i<n;i++){
    int a;cin>>a;asum+=a;
  }
  for(int i=0;i<n;i++){
    int b;cin>>b;bsum+=b;
  }
  asum%=MOD;bsum%=MOD;
  int ans=0;
  for(int i=1;i*3<=k&&2*i<=n;i++){//i回降りてi回登る->k-2i個下を旅する
    if(k-2*i>n-i)continue;
    int tmp=nCk(k-3*i+i-1,i-1)*nCk(n-k+2*i-i+i-1,i-1)%MOD;
    (tmp*=n)%=MOD;
    (tmp*=pw(i,MOD-2))%=MOD;
    (tmp*=pw(2,i))%=MOD;
    (tmp*=Factorial[i])%=MOD;
    int A=asum*2*i%MOD*pw(n,MOD-2)%MOD;
    int B=bsum*(k-2*i)%MOD*pw(n,MOD-2)%MOD;
    (tmp*=A+B)%=MOD;
    (ans+=tmp)%=MOD;
  }
  cout<<ans<<endl;
}
accuracy: 1
time_ms: 600
memory_kb: 80816
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int long long
const int MOD=998244353;

int pw(int n,int k){
  assert(k>=0);
  int res=1;
  while(k){
    if(k&1)(res*=n)%=MOD;
    (n*=n)%=MOD;
    k>>=1;
  }
  return res;
}
std::vector<int> Factorial(5e6),Finverse(5e6);
inline void Cinit(){
  Factorial[0]=1;
  for(int i=1;i<5e6;i++)Factorial[i]=(Factorial[i-1]*i)%MOD;
  Finverse[4999999]=pw(Factorial[4999999],MOD-2);
  for(int i=4999998;i>=0;i--)Finverse[i]=(i+1)*Finverse[i+1]%MOD;
}
int nCk(int n,int k){
  assert(n>=k&&k>=0);
  if(n<k)return 0;if(k<0)return 0;
  assert(n<5000000&&k<5000000);
  if(!Factorial[0])Cinit();
  int res=Factorial[n];
  (res*=Finverse[k])%=MOD;
  (res*=Finverse[n-k])%=MOD;
  return res;
}

signed main(){
  int n,k;cin>>n>>k;
  int asum=0,bsum=0;
  for(int i=0;i<n;i++){
    int a;cin>>a;asum+=a;
  }
  for(int i=0;i<n;i++){
    int b;cin>>b;bsum+=b;
  }
  asum%=MOD;bsum%=MOD;
  int ans=0;
  for(int i=1;i*3<=k&&2*i<=n;i++){//i回降りてi回登る->k-2i個下を旅する
    if(k-2*i>n-i)continue;
    int tmp=nCk(k-3*i+i-1,i-1)*nCk(n-k+2*i-i+i-1,i-1)%MOD;
    (tmp*=n)%=MOD;
    (tmp*=pw(n-(k-2*i),MOD-2))%=MOD;
    (tmp*=pw(2,i))%=MOD;
    (tmp*=Factorial[i])%=MOD;
    int A=asum*2*i%MOD*pw(n,MOD-2)%MOD;
    int B=bsum*(k-2*i)%MOD*pw(n,MOD-2)%MOD;
    (tmp*=A+B)%=MOD;
    (ans+=tmp)%=MOD;
  }
  cout<<ans<<endl;
}
accuracy: 0.1
time_ms: 60
memory_kb: 80728
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int long long
const int MOD=998244353;

int pw(int n,int k){
  assert(k>=0);
  int res=1;
  while(k){
    if(k&1)(res*=n)%=MOD;
    (n*=n)%=MOD;
    k>>=1;
  }
  return res;
}
std::vector<int> Factorial(5e6),Finverse(5e6);
inline void Cinit(){
  Factorial[0]=1;
  for(int i=1;i<5e6;i++)Factorial[i]=(Factorial[i-1]*i)%MOD;
  Finverse[4999999]=pw(Factorial[4999999],MOD-2);
  for(int i=4999998;i>=0;i--)Finverse[i]=(i+1)*Finverse[i+1]%MOD;
}
int nCk(int n,int k){
  if(n<k)return 0;if(k<0)return 0;
  assert(n<5000000&&k<5000000);
  if(!Factorial[0])Cinit();
  int res=Factorial[n];
  (res*=Finverse[k])%=MOD;
  (res*=Finverse[n-k])%=MOD;
  return res;
}

signed main(){
  int n,k;cin>>n>>k;
  int asum=0,bsum=0;
  for(int i=0;i<n;i++){
    int a;cin>>a;asum+=a;
  }
  for(int i=0;i<n;i++){
    int b;cin>>b;bsum+=b;
  }
  asum%=MOD;bsum%=MOD;
  int ans=0;
  for(int i=1;i*3<=k&&2*i<=n;i++){//i回降りてi回登る->k-2i個下を旅する
    if(k-2*i>n-i)continue;
    int tmp=nCk(k-3*i+i-1,i-1)*nCk(n-k+2*i-i+i-1,i-1)%MOD;
    (tmp*=n)%=MOD;
    (tmp*=pw(n-(k-2*i),MOD-2))%=MOD;
    (tmp*=pw(2,i))%=MOD;
    (tmp*=Factorial[i])%=MOD;
    int A=asum*2*i%MOD*pw(n,MOD-2)%MOD;
    int B=bsum*(k-2*i)%MOD*pw(n,MOD-2)%MOD;
    (tmp*=A+B)%=MOD;
    (ans+=tmp)%=MOD;
  }
  cout<<ans<<endl;
}
accuracy: 0.1
time_ms: 60
memory_kb: 80768
final_rank: 18