#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define setIO(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
#define m_p make_pair
#define sz(x) (int)(x.size())
#define out(x) cerr << #x << " = " << x << " "
#define outln(x) cerr << #x << " = " << x << endl
#define outarr(x, l, r) {cerr << #x"[" << l << " ~ " << r << "] = "; for (int _ = l; _ <= r; ++_) cerr << x[_] << " "; cerr << endl;}

const int mod = 998244353, inv2 = 499122177;
struct Z {
	int x;
	Z() {}
	Z(int _):x(_) {}
};
Z operator + (const Z &a, const Z &b) {const int o = a.x + b.x; return o >= mod ? o - mod : o;}
Z operator - (const Z &a, const Z &b) {const int o = a.x - b.x + mod; return o >= mod ? o - mod : o;}
Z operator * (const Z &a, const Z &b) {const int o = (int)(1LL * a.x * b.x % mod); return o;}
Z& operator += (Z &a, const Z &b) {return a = a + b;}
Z& operator -= (Z &a, const Z &b) {return a = a - b;}
Z& operator *= (Z &a, const Z &b) {return a = a * b;}
template <class T> Z qpow(Z a, T b) {
	Z ans = 1;
	while (b) {
		if (b & 1) ans = ans * a;
		a = a * a;
		b >>= 1;
	}
	return ans;
}
Z operator / (const Z &a, const Z &b) {return a * qpow(b, mod - 2);}
Z& operator /= (Z &a, const Z &b) {return a = a / b;}
ostream& operator << (ostream &out, const Z &a) {out << a.x; return out;}

int Typ, t;
ull seed;
ull rd(ull &x) {
	x ^= (x << 13);
	x ^= (x >> 7);
	x ^= (x << 17);
	return x;
}

const int N = 2000005;
int n, q, x;
Z a[N], c[N];
ll k_max;
bool mem[N << 1];
Z seq[N << 1];
int P; Z all, invn, sum = 0;

void init() {
	scanf("%d%d%d%lld", &n, &q, &x, &k_max);
	sum = 0;
	for (int i = 1; i <= n; ++i) scanf("%d", &a[i].x), sum += a[i];
	invn = Z(1) / n;
	for (int i = 0; i < n + n; ++i) mem[i] = 0, seq[i] = 0;
}

/*Z calc(ll k, int i) {
	Z ans = 0;
	int r1 = 1LL * P * i % (n + n);
	int r2 = 1LL * P * (i - 1) % (n + n);
	ans -= r1 * invn;
	ans += r2 * invn;
	if (r1 >= x) ans += 1;
	if (r1 >= n + n - x + 1) ans += 1;
	if (r2 >= x) ans -= 1;
	if (r2 >= n + n - x + 1) ans -= 1;
	return ans;
}*/

Z query(ll k) {
	if (k == 0) return a[x];
	ll t = k; int A = 2; P = 1;
	while (t) {
		if (t & 1) P = 1LL * P * A % (n + n);
		A = 1LL * A * A % (n + n);
		t >>= 1;
	}
	if (mem[P]) return seq[P];
	all = qpow(2, k);
	// (2 ^ k) % 2n = P
	Z ans = all * invn * sum;
	for (int i = 0, cur = 0; i <= n / 2; ++i) {
		c[i] = cur * invn;
		if (cur >= x) c[i] -= 1;
		if (cur >= n + n - x + 1) c[i] -= 1;
		cur = (cur + P) % (n + n);
	}
	for (int i = 1; i <= n / 2; ++i) {
		ans += (a[i] + a[n + 1 - i]) * (c[i - 1] - c[i]);
	}
	ans *= qpow(inv2, k);
	mem[P] = 1;
	return seq[P] = ans;
}

void solve() {
	ll ans = 0;
	for (int i = 1; i <= q; ++i) {
		ll k = rd(seed) % k_max;
		Z res = query(k);
		ans ^= 1LL * res.x * i;
	}
	printf("%lld\n", ans);
}

int main() {
	setIO("noodle");
	scanf("%d%d%llu", &Typ, &t, &seed);
	while (t--) {
		init();
		solve();
	}
	return 0;
}
