結果

問題 No.3226 2×2行列累乗
ユーザー ynymxiaolongbao
提出日時 2025-08-08 22:00:47
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 2 ms / 2,000 ms
コード長 35,388 bytes
コンパイル時間 4,850 ms
コンパイル使用メモリ 321,312 KB
実行使用メモリ 7,716 KB
最終ジャッジ日時 2025-08-08 22:00:53
合計ジャッジ時間 5,344 ms
ジャッジサーバーID
(参考情報)
judge1 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 27
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 lll;
using ull = unsigned long long;
typedef pair<ll,ll> pll;
typedef vector<ll> vll;
typedef vector<pll> vpll;
template<class T> using pqmin = priority_queue<T, vector<T>, greater<T>>;
template<class T> using pqmax = priority_queue<T>;
const ll inf=LLONG_MAX/3;
const ll dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const ll dy[] = {1, 0, -1, 0, 1, 1, -1, -1};
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define si(x) ll(x.size())
#define rept(n) for(ll _ovo_=0;_ovo_<n;_ovo_++)
#define rep(i,n) for(ll i=0;i<n;i++)
#define per(i,n) for(ll i=n-1;i>=0;i--)
#define rng(i,l,r) for(ll i=l;i<r;i++)
#define gnr(i,l,r) for(ll i=r-1;i>=l;i--)
#define fore(i, a) for(auto &&i : a)
#define fore2(a, b, v) for(auto &&[a, b] : v)
#define fore3(a, b, c, v) for(auto &&[a, b, c] : v)
template<class T> bool chmin(T& a, const T& b){ if(a <= b) return 0; a = b; return 1; }
template<class T> bool chmax(T& a, const T& b){ if(a >= b) return 0; a = b; return 1; }
template<class T, class U> bool chmin(T& a, const U& b){ return chmin(a, (T)b); }
template<class T, class U> bool chmax(T& a, const U& b){ return chmax(a, (T)b); }
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define vec(type,name,...) vector<type>name(__VA_ARGS__)
#define VEC(type,name,size) vector<type>name(size);in(name)
#define VLL(name,size) vector<ll>name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>> name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>> name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>> name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
#define SUM(...) accumulate(all(__VA_ARGS__),0LL)
template<class T> auto min(const T& a){ return *min_element(all(a)); }
template<class T> auto max(const T& a){ return *max_element(all(a)); }
template<class T, class F = less<>> void sor(T& a, F b = F{}){ sort(all(a), b); }
template<class T> void uniq(T& a){ sor(a); a.erase(unique(all(a)), end(a)); }
template<class T, class F = less<>> map<T,vector<ll> > ivm(vector<T>& a, F b = F{}){ map<T,vector<ll> > ret; rep(i,si(a))ret[a[i]].push_back(i); return ret;}
template<class T, class F = less<>> map<T,ll> ivc(vector<T>& a, F b = F{}){ map<T,ll> ret; rep(i,si(a))ret[a[i]]++; return ret;}
template<class T, class F = less<>> vector<T> ivp(vector<T> a){ vector<ll> ret(si(a)); rep(i,si(a))ret[a[i]] = i; return ret;}
template<class T, class F = less<>> vector<ll> rev(vector<T> a){ reverse(all(a)); return a;}
template<class T, class F = less<>> vector<ll> sortby(vector<T> a, F b = F{}){vector<ll> w = a; sor(w,b); vector<pll> v; rep(i,si(a))v.eb(a[i],i); sor(v); if(w[0] != v[0].first)reverse(all(v)); vector<ll> ret; rep(i,si(v))ret.pb(v[i].second); return ret;}
template<class T, class P> vector<T> filter(vector<T> a,P f){vector<T> ret;rep(i,si(a)){if(f(a[i]))ret.pb(a[i]);}return ret;}
template<class T, class P> vector<ll> filter_id(vector<T> a,P f){vector<ll> ret;rep(i,si(a)){if(f(a[i]))ret.pb(i);}return ret;}
ll monotone_left(function<bool(ll)> f){ll l = -1,r = (ll)1e18 + 1; assert(f(l + 1) >= f(r - 1)); while(l + 1 < r){ll mid = (l + r)>> 1; (f(mid)?l:r) = mid;} return l;}
ll monotone_left(ll l,ll r,function<bool(ll)> f){l--; assert(f(l + 1) >= f(r - 1)); while(l + 1 < r){ll mid = (l + r)>> 1; (f(mid)?l:r) = mid;} return l;}
ll monotone_right(function<bool(ll)> f){ll l = -1,r = (ll)1e18 + 1; assert(f(l + 1) <= f(r - 1)); while(l + 1 < r){ll mid = (l + r)>> 1; (f(mid)?r:l) = mid;} return r;}
ll monotone_right(ll l,ll r,function<bool(ll)> f){l--; assert(f(l + 1) <= f(r - 1)); while(l + 1 < r){ll mid = (l + r)>> 1; (f(mid)?r:l) = mid;} return r;}
double monotone_double_left(double l,double r,function<bool(double)> f){assert(f(l) >= f(r)); rep(_,100){double mid = (l + r) / 2.0; (f(mid)?l:r) = mid;} return l;}
double monotone_double_right(double l,double r,function<bool(double)> f){assert(f(l) <= f(r)); rep(_,100){double mid = (l + r) / 2.0; (f(mid)?l:r) = mid;} return r;}
template<class S> S unimodal_max(ll l,ll r,function<S(ll)> f){while(l + 2 < r){ll m1 = l + (r - l) / 3,m2 = l + (r - l) / 3 * 2; if(f(m1) < f(m2))l = m1; else r = m2;} S ret = f(l); rng(k,l,r + 1)chmax(ret,f(k)); return ret;}
template<class S> S unimodal_min(ll l,ll r,function<S(ll)> f){while(l + 2 < r){ll m1 = l + (r - l) / 3,m2 = l + (r - l) / 3 * 2; if(f(m1) > f(m2))l = m1; else r = m2;} S ret = f(l); rng(k,l,r + 1)chmin(ret,f(k)); return ret;}
vector<pll> neighbor4(ll x,ll y,ll h,ll w){vector<pll> ret;rep(dr,4){ll xx = x + dx[dr],yy = y + dy[dr]; if(0 <= xx && xx < h && 0 <= yy && yy <w)ret.eb(xx,yy);} return ret;};
vector<pll> neighbor8(ll x,ll y,ll h,ll w){vector<pll> ret;rep(dr,8){ll xx = x + dx[dr],yy = y + dy[dr]; if(0 <= xx && xx < h && 0 <= yy && yy <w)ret.eb(xx,yy);} return ret;};

void outb(bool x){cout<<(x?"Yes":"No")<<"\n";}
ll max(int x, ll y) { return max((ll)x, y); }
ll max(ll x, int y) { return max(x, (ll)y); }
int min(int x, ll y) { return min((ll)x, y); }
int min(ll x, int y) { return min(x, (ll)y); }
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define lbg(c, x) distance((c).begin(), lower_bound(all(c), (x), greater{}))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define ubg(c, x) distance((c).begin(), upper_bound(all(c), (x), greater{}))
ll gcd(ll a,ll b){return (b?gcd(b,a%b):a);}
vector<pll> factor(ull x){ vector<pll> ans; for(ull i = 2; i * i <= x; i++) if(x % i == 0){ ans.push_back({i, 1}); while((x /= i) % i == 0) ans.back().second++; } if(x != 1) ans.push_back({x, 1}); return ans; }
vector<ll> divisor(ull x){ vector<ll> ans; for(ull i = 1; i * i <= x; i++) if(x % i == 0) ans.push_back(i); per(i,ans.size() - (ans.back() * ans.back() == x)) ans.push_back(x / ans[i]); return ans; }
vll prime_table(ll n){vec(ll,isp,n+1,1);vll res;rng(i,2,n+1)if(isp[i]){res.pb(i);for(ll j=i*i;j<=n;j+=i)isp[j]=0;}return res;}
ll powll(lll x,ll y){lll res = 1; while(y){ if(y & 1)res = res * x; x = x * x; y >>= 1;} return res;}
ll powmod(lll x,ll y,lll mod){lll res=1; while(y){ if(y&1)res=res*x%mod; x=x*x%mod; y>>=1;} return res; }
ll modinv(ll a,ll m){ll b=m,u=1,v=0;while(b){ll t=a/b;a-=t*b;swap(a,b);u-=t*v;swap(u,v);}u%=m;if(u<0)u+=m;return u;}

template <class T, class S> pair<T, S> operator-(const pair<T, S> &x) { return pair<T, S>(-x.first, -x.second); }
template <class T, class S> pair<T, S> operator-(const pair<T, S> &x, const pair<T, S> &y) { return pair<T, S>(x.fi - y.fi, x.se - y.se); }
template <class T, class S> pair<T, S> operator+(const pair<T, S> &x, const pair<T, S> &y) { return pair<T, S>(x.fi + y.fi, x.se + y.se); }
template <class T> pair<T, T> operator&(const pair<T, T> &l, const pair<T, T> &r) { return pair<T, T>(max(l.fi, r.fi), min(l.se, r.se)); }
template <class T, class S> pair<T, S> operator+=(pair<T, S> &l, const pair<T, S> &r) { return l = l + r; }
template <class T, class S> pair<T, S> operator-=(pair<T, S> &l, const pair<T, S> &r) { return l = l - r; }
template <class T> bool intersect(const pair<T, T> &l, const pair<T, T> &r) { return (l.se < r.se ? r.fi < l.se : l.fi < r.se); }

template <class T> vector<T> &operator++(vector<T> &v) {
		fore(e, v) e++;
		return v;
}
template <class T> vector<T> operator++(vector<T> &v, int) {
		auto res = v;
		fore(e, v) e++;
		return res;
}
template <class T> vector<T> &operator--(vector<T> &v) {
		fore(e, v) e--;
		return v;
}
template <class T> vector<T> operator--(vector<T> &v, int) {
		auto res = v;
		fore(e, v) e--;
		return res;
}
template <class T> vector<T> &operator+=(vector<T> &l, const vector<T> &r) {
		fore(e, r) l.eb(e);
		return l;
}

template<class... Ts> void in(Ts&... t);
[[maybe_unused]] void print(){}
template<class T, class... Ts> void print(const T& t, const Ts&... ts);
template<class... Ts> void out(const Ts&... ts){ print(ts...); cout << '\n'; }
namespace IO{
#define VOID(a) decltype(void(a))
struct S{ S(){ cin.tie(nullptr)->sync_with_stdio(0); fixed(cout).precision(12); } }S;
template<int I> struct P : P<I-1>{};
template<> struct P<0>{};
template<class T> void i(T& t){ i(t, P<3>{}); }
void i(vector<bool>::reference t, P<3>){ int a; i(a); t = a; }
template<class T> auto i(T& t, P<2>) -> VOID(cin >> t){ cin >> t; }
template<class T> auto i(T& t, P<1>) -> VOID(begin(t)){ for(auto&& x : t) i(x); }
template<class T, size_t... idx> void ituple(T& t, index_sequence<idx...>){ in(get<idx>(t)...); }
template<class T> auto i(T& t, P<0>) -> VOID(tuple_size<T>{}){ ituple(t, make_index_sequence<tuple_size<T>::value>{}); }
template<class T> void o(const T& t){ o(t, P<4>{}); }
template<size_t N> void o(const char (&t)[N], P<4>){ cout << t; }
template<class T, size_t N> void o(const T (&t)[N], P<3>){ o(t[0]); for(size_t i = 1; i < N; i++){ o(' '); o(t[i]); } }
template<class T> auto o(const T& t, P<2>) -> VOID(cout << t){ cout << t; }
template<class T> auto o(const T& t, P<1>) -> VOID(begin(t)){ bool first = 1; for(auto&& x : t) { if(first) first = 0; else o(' '); o(x); } }
template<class T, size_t... idx> void otuple(const T& t, index_sequence<idx...>){ print(get<idx>(t)...); }
template<class T> auto o(T& t, P<0>) -> VOID(tuple_size<T>{}){ otuple(t, make_index_sequence<tuple_size<T>::value>{}); }
#undef VOID
}
#define unpack(a) (void)initializer_list<int>{(a, 0)...}
template<class... Ts> void in(Ts&... t){ unpack(IO::i(t)); }
template<class T, class... Ts> void print(const T& t, const Ts&... ts){ IO::o(t); unpack(IO::o((cout << ' ', ts))); }
#undef unpack
template <typename T>
struct Matrix {
		vector<vector<T>> A;
		int n, m;

		Matrix(int n, int m) : A(n, vector<T>(m, 0)), n(n), m(m) {}

		inline const vector<T> &operator[](int k) const { return A[k]; }

		inline vector<T> &operator[](int k) { return A[k]; }

		static Matrix I(int l) {
				Matrix ret(l, l);
				for (int i = 0; i < l; i++) ret[i][i] = 1;
				return ret;
		}

		Matrix &operator*=(const Matrix &B) {
				assert(m == B.n);
				Matrix ret(n, B.m);
				for (int i = 0; i < n; i++) {
						for (int k = 0; k < m; k++) {
								for (int j = 0; j < B.m; j++) ret[i][j] += A[i][k] * B[k][j];
						}
				}
				swap(A, ret.A);
				m = B.m;
				return *this;
		}

		Matrix operator*(const Matrix &B) const { return Matrix(*this) *= B; }

		Matrix pow(long long k) const {
				assert(n == m);
				Matrix now = *this, ret = I(n);
				for (; k > 0; k >>= 1, now *= now) {
						if (k & 1) ret *= now;
				}
				return ret;
		}

		bool eq(const T &a, const T &b) const {
				return a == b;
				// return abs(a-b) <= EPS;
		}

		// 行基本変形を用いて簡約化を行い、(rank, det) の組を返す
		pair<int, T> row_reduction(vector<T> &b) {
				assert((int)b.size() == n);
				if (n == 0) return make_pair(0, m > 0 ? 0 : 1);
				int check = 0, rank = 0;
				T det = (n == m ? 1 : 0);
				assert(b.size() == n);
				for (int j = 0; j < m; j++) {
						int pivot = check;
						for (int i = check; i < n; i++) {
								if (A[i][j] != 0) pivot = i;
								// if(abs(A[i][j]) > abs(A[pivot][j])) pivot = i; // T が小数の場合はこちら
						}
						if (check != pivot) det *= T(-1);
						swap(A[check], A[pivot]), swap(b[check], b[pivot]);
						if (eq(A[check][j], T(0))) {
								det = T(0);
								continue;
						}
						rank++;
						det *= A[check][j];
						T r = T(1) / A[check][j];
						for (int k = j + 1; k < m; k++) A[check][k] *= r;
						b[check] *= r;
						A[check][j] = T(1);
						for (int i = 0; i < n; i++) {
								if (i == check) continue;
								if (!eq(A[i][j], 0)) {
										for (int k = j + 1; k < m; k++) A[i][k] -= A[i][j] * A[check][k];
										b[i] -= A[i][j] * b[check];
								}
								A[i][j] = T(0);
						}
						if (++check == n) break;
				}
				return make_pair(rank, det);
		}

		pair<int, T> row_reduction() {
				vector<T> b(n, T(0));
				return row_reduction(b);
		}

		// 行基本変形を行い、逆行列を求める
		pair<bool, Matrix> inverse() {
				if (n != m) return make_pair(false, Matrix(0, 0));
				if (n == 0) return make_pair(true, Matrix(0, 0));
				Matrix ret = I(n);
				for (int j = 0; j < n; j++) {
						int pivot = j;
						for (int i = j; i < n; i++) {
								if (A[i][j] != 0) pivot = i;
								// if(abs(A[i][j]) > abs(A[pivot][j])) pivot = i; // T が小数の場合はこちら
						}
						swap(A[j], A[pivot]), swap(ret[j], ret[pivot]);
						if (eq(A[j][j], T(0))) return make_pair(false, Matrix(0, 0));
						T r = T(1) / A[j][j];
						for (int k = j + 1; k < n; k++) A[j][k] *= r;
						for (int k = 0; k < n; k++) ret[j][k] *= r;
						A[j][j] = T(1);
						for (int i = 0; i < n; i++) {
								if (i == j) continue;
								if (!eq(A[i][j], T(0))) {
										for (int k = j + 1; k < n; k++) A[i][k] -= A[i][j] * A[j][k];
										for (int k = 0; k < n; k++) ret[i][k] -= A[i][j] * ret[j][k];
								}
								A[i][j] = T(0);
						}
				}
				return make_pair(true, ret);
		}

		// Ax = b の解の 1 つと解空間の基底の組を返す
		vector<vector<T>> Gaussian_elimination(vector<T> b) {
				row_reduction(b);
				vector<vector<T>> ret;
				vector<int> p(n, m);
				vector<bool> is_zero(m, true);
				for (int i = 0; i < n; i++) {
						for (int j = 0; j < m; j++) {
								if (!eq(A[i][j], T(0))) {
										p[i] = j;
										break;
								}
						}
						if (p[i] < m) {
								is_zero[p[i]] = false;
						} else if (!eq(b[i], T(0))) {
								return {};
						}
				}
				vector<T> x(m, T(0));
				for (int i = 0; i < n; i++) {
						if (p[i] < m) x[p[i]] = b[i];
				}
				ret.push_back(x);
				for (int j = 0; j < m; j++) {
						if (!is_zero[j]) continue;
						x[j] = T(1);
						for (int i = 0; i < n; i++) {
								if (p[i] < m) x[p[i]] = -A[i][j];
						}
						ret.push_back(x);
						x[j] = T(0);
				}
				return ret;
		}
};

#ifdef _MSC_VER
#include <intrin.h>
#endif
 
namespace atcoder {
 
namespace internal {
 
int ceil_pow2(int n) {
	int x = 0;
	while ((1U << x) < (unsigned int)(n)) x++;
	return x;
}
 
constexpr int bsf_constexpr(unsigned int n) {
	int x = 0;
	while (!(n & (1 << x))) x++;
	return x;
}
 
int bsf(unsigned int n) {
#ifdef _MSC_VER
	unsigned long index;
	_BitScanForward(&index, n);
	return index;
#else
	return __builtin_ctz(n);
#endif
}
 
}  // namespace internal
 
}  // namespace atcoder
 
 
#include <cassert>
#include <numeric>
#include <type_traits>
 
#ifdef _MSC_VER
#include <intrin.h>
#endif
 
 
#include <utility>
 
#ifdef _MSC_VER
#include <intrin.h>
#endif
 
namespace atcoder {
 
namespace internal {
 
constexpr long long safe_mod(long long x, long long m) {
	x %= m;
	if (x < 0) x += m;
	return x;
}
 
struct barrett {
	unsigned int _m;
	unsigned long long im;
 
	explicit barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}
 
	unsigned int umod() const { return _m; }
 
	unsigned int mul(unsigned int a, unsigned int b) const {
 
		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;
	}
};
 
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;
}
 
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;
	constexpr long long bases[3] = {2, 7, 61};
	for (long long a : bases) {
		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);
 
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};
 
	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
 
 
		auto tmp = s;
		s = t;
		t = tmp;
		tmp = m0;
		m0 = m1;
		m1 = tmp;
	}
	if (m0 < 0) m0 += b / s;
	return {s, m0};
}
 
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);
 
unsigned long long floor_sum_unsigned(unsigned long long n,
										unsigned long long m,
										unsigned long long a,
										unsigned long long b) {
	unsigned long long ans = 0;
	while (true) {
		if (a >= m) {
			ans += n * (n - 1) / 2 * (a / m);
			a %= m;
		}
		if (b >= m) {
			ans += n * (b / m);
			b %= m;
		}
 
		unsigned long long y_max = a * n + b;
		if (y_max < m) break;
		n = (unsigned long long)(y_max / m);
		b = (unsigned long long)(y_max % m);
		std::swap(m, a);
	}
	return ans;
}
 
}  // 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
 
 
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());
	}
 
	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());
	}
 
	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
 
 
namespace atcoder {
 
namespace internal {
 
template <class mint,
			int g = internal::primitive_root<mint::mod()>,
			internal::is_static_modint_t<mint>* = nullptr>
struct fft_info {
	static constexpr int rank2 = bsf_constexpr(mint::mod() - 1);
	std::array<mint, rank2 + 1> root;   // root[i]^(2^i) == 1
	std::array<mint, rank2 + 1> iroot;  // root[i] * iroot[i] == 1
 
	std::array<mint, std::max(0, rank2 - 2 + 1)> rate2;
	std::array<mint, std::max(0, rank2 - 2 + 1)> irate2;
 
	std::array<mint, std::max(0, rank2 - 3 + 1)> rate3;
	std::array<mint, std::max(0, rank2 - 3 + 1)> irate3;
 
	fft_info() {
		root[rank2] = mint(g).pow((mint::mod() - 1) >> rank2);
		iroot[rank2] = root[rank2].inv();
		for (int i = rank2 - 1; i >= 0; i--) {
			root[i] = root[i + 1] * root[i + 1];
			iroot[i] = iroot[i + 1] * iroot[i + 1];
		}
 
		{
			mint prod = 1, iprod = 1;
			for (int i = 0; i <= rank2 - 2; i++) {
				rate2[i] = root[i + 2] * prod;
				irate2[i] = iroot[i + 2] * iprod;
				prod *= iroot[i + 2];
				iprod *= root[i + 2];
			}
		}
		{
			mint prod = 1, iprod = 1;
			for (int i = 0; i <= rank2 - 3; i++) {
				rate3[i] = root[i + 3] * prod;
				irate3[i] = iroot[i + 3] * iprod;
				prod *= iroot[i + 3];
				iprod *= root[i + 3];
			}
		}
	}
};
 
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly(std::vector<mint>& a) {
	int n = int(a.size());
	int h = internal::ceil_pow2(n);
 
	static const fft_info<mint> info;
 
	int len = 0;  // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed
	while (len < h) {
		if (h - len == 1) {
			int p = 1 << (h - len - 1);
			mint rot = 1;
			for (int s = 0; s < (1 << len); s++) {
				int offset = s << (h - len);
				for (int i = 0; i < p; i++) {
					auto l = a[i + offset];
					auto r = a[i + offset + p] * rot;
					a[i + offset] = l + r;
					a[i + offset + p] = l - r;
				}
				if (s + 1 != (1 << len))
					rot *= info.rate2[bsf(~(unsigned int)(s))];
			}
			len++;
		} else {
			int p = 1 << (h - len - 2);
			mint rot = 1, imag = info.root[2];
			for (int s = 0; s < (1 << len); s++) {
				mint rot2 = rot * rot;
				mint rot3 = rot2 * rot;
				int offset = s << (h - len);
				for (int i = 0; i < p; i++) {
					auto mod2 = 1ULL * mint::mod() * mint::mod();
					auto a0 = 1ULL * a[i + offset].val();
					auto a1 = 1ULL * a[i + offset + p].val() * rot.val();
					auto a2 = 1ULL * a[i + offset + 2 * p].val() * rot2.val();
					auto a3 = 1ULL * a[i + offset + 3 * p].val() * rot3.val();
					auto a1na3imag =
						1ULL * mint(a1 + mod2 - a3).val() * imag.val();
					auto na2 = mod2 - a2;
					a[i + offset] = a0 + a2 + a1 + a3;
					a[i + offset + 1 * p] = a0 + a2 + (2 * mod2 - (a1 + a3));
					a[i + offset + 2 * p] = a0 + na2 + a1na3imag;
					a[i + offset + 3 * p] = a0 + na2 + (mod2 - a1na3imag);
				}
				if (s + 1 != (1 << len))
					rot *= info.rate3[bsf(~(unsigned int)(s))];
			}
			len += 2;
		}
	}
}
 
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly_inv(std::vector<mint>& a) {
	int n = int(a.size());
	int h = internal::ceil_pow2(n);
 
	static const fft_info<mint> info;
 
	int len = h;  // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed
	while (len) {
		if (len == 1) {
			int p = 1 << (h - len);
			mint irot = 1;
			for (int s = 0; s < (1 << (len - 1)); s++) {
				int offset = s << (h - len + 1);
				for (int i = 0; i < p; i++) {
					auto l = a[i + offset];
					auto r = a[i + offset + p];
					a[i + offset] = l + r;
					a[i + offset + p] =
						(unsigned long long)(mint::mod() + l.val() - r.val()) *
						irot.val();
					;
				}
				if (s + 1 != (1 << (len - 1)))
					irot *= info.irate2[bsf(~(unsigned int)(s))];
			}
			len--;
		} else {
			int p = 1 << (h - len);
			mint irot = 1, iimag = info.iroot[2];
			for (int s = 0; s < (1 << (len - 2)); s++) {
				mint irot2 = irot * irot;
				mint irot3 = irot2 * irot;
				int offset = s << (h - len + 2);
				for (int i = 0; i < p; i++) {
					auto a0 = 1ULL * a[i + offset + 0 * p].val();
					auto a1 = 1ULL * a[i + offset + 1 * p].val();
					auto a2 = 1ULL * a[i + offset + 2 * p].val();
					auto a3 = 1ULL * a[i + offset + 3 * p].val();
 
					auto a2na3iimag =
						1ULL *
						mint((mint::mod() + a2 - a3) * iimag.val()).val();
 
					a[i + offset] = a0 + a1 + a2 + a3;
					a[i + offset + 1 * p] =
						(a0 + (mint::mod() - a1) + a2na3iimag) * irot.val();
					a[i + offset + 2 * p] =
						(a0 + a1 + (mint::mod() - a2) + (mint::mod() - a3)) *
						irot2.val();
					a[i + offset + 3 * p] =
						(a0 + (mint::mod() - a1) + (mint::mod() - a2na3iimag)) *
						irot3.val();
				}
				if (s + 1 != (1 << (len - 2)))
					irot *= info.irate3[bsf(~(unsigned int)(s))];
			}
			len -= 2;
		}
	}
}
 
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution_naive(const std::vector<mint>& a,
									const std::vector<mint>& b) {
	int n = int(a.size()), m = int(b.size());
	std::vector<mint> ans(n + m - 1);
	if (n < m) {
		for (int j = 0; j < m; j++) {
			for (int i = 0; i < n; i++) {
				ans[i + j] += a[i] * b[j];
			}
		}
	} else {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				ans[i + j] += a[i] * b[j];
			}
		}
	}
	return ans;
}
 
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution_fft(std::vector<mint> a, std::vector<mint> b) {
	int n = int(a.size()), m = int(b.size());
	int z = 1 << internal::ceil_pow2(n + m - 1);
	a.resize(z);
	internal::butterfly(a);
	b.resize(z);
	internal::butterfly(b);
	for (int i = 0; i < z; i++) {
		a[i] *= b[i];
	}
	internal::butterfly_inv(a);
	a.resize(n + m - 1);
	mint iz = mint(z).inv();
	for (int i = 0; i < n + m - 1; i++) a[i] *= iz;
	return a;
}
 
}  // namespace internal
 
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution(std::vector<mint>&& a, std::vector<mint>&& b) {
	int n = int(a.size()), m = int(b.size());
	if (!n || !m) return {};
	if (std::min(n, m) <= 60) return convolution_naive(a, b);
	return internal::convolution_fft(a, b);
}
 
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution(const std::vector<mint>& a,
								const std::vector<mint>& b) {
	int n = int(a.size()), m = int(b.size());
	if (!n || !m) return {};
	if (std::min(n, m) <= 60) return convolution_naive(a, b);
	return internal::convolution_fft(a, b);
}
 
template <unsigned int mod = 998244353,
			class T,
			std::enable_if_t<internal::is_integral<T>::value>* = nullptr>
std::vector<T> convolution(const std::vector<T>& a, const std::vector<T>& b) {
	int n = int(a.size()), m = int(b.size());
	if (!n || !m) return {};
 
	using mint = static_modint<mod>;
	std::vector<mint> a2(n), b2(m);
	for (int i = 0; i < n; i++) {
		a2[i] = mint(a[i]);
	}
	for (int i = 0; i < m; i++) {
		b2[i] = mint(b[i]);
	}
	auto c2 = convolution(move(a2), move(b2));
	std::vector<T> c(n + m - 1);
	for (int i = 0; i < n + m - 1; i++) {
		c[i] = c2[i].val();
	}
	return c;
}
 
std::vector<long long> convolution_ll(const std::vector<long long>& a,
										const std::vector<long long>& b) {
	int n = int(a.size()), m = int(b.size());
	if (!n || !m) return {};
 
	static constexpr unsigned long long MOD1 = 754974721;  // 2^24
	static constexpr unsigned long long MOD2 = 167772161;  // 2^25
	static constexpr unsigned long long MOD3 = 469762049;  // 2^26
	static constexpr unsigned long long M2M3 = MOD2 * MOD3;
	static constexpr unsigned long long M1M3 = MOD1 * MOD3;
	static constexpr unsigned long long M1M2 = MOD1 * MOD2;
	static constexpr unsigned long long M1M2M3 = MOD1 * MOD2 * MOD3;
 
	static constexpr unsigned long long i1 =
		internal::inv_gcd(MOD2 * MOD3, MOD1).second;
	static constexpr unsigned long long i2 =
		internal::inv_gcd(MOD1 * MOD3, MOD2).second;
	static constexpr unsigned long long i3 =
		internal::inv_gcd(MOD1 * MOD2, MOD3).second;
 
	auto c1 = convolution<MOD1>(a, b);
	auto c2 = convolution<MOD2>(a, b);
	auto c3 = convolution<MOD3>(a, b);
 
	std::vector<long long> c(n + m - 1);
	for (int i = 0; i < n + m - 1; i++) {
		unsigned long long x = 0;
		x += (c1[i] * i1) % MOD1 * M2M3;
		x += (c2[i] * i2) % MOD2 * M1M3;
		x += (c3[i] * i3) % MOD3 * M1M2;
		long long diff =
			c1[i] - internal::safe_mod((long long)(x), (long long)(MOD1));
		if (diff < 0) diff += MOD1;
		static constexpr unsigned long long offset[5] = {
			0, 0, M1M2M3, 2 * M1M2M3, 3 * M1M2M3};
		x -= offset[diff % 5];
		c[i] = x;
	}
 
	return c;
}
 
}  // namespace atcoder
 

using namespace atcoder;
// using mint=modint998244353;
using mint = modint;
using vmint=vector<mint>;


using mat=Matrix<mint>;

int main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	ll A,B,C,D,S,T,N,K;
	cin>>A>>B>>C>>D>>S>>T>>N>>K;
	mint::set_mod(K);
	ll n = 2;
	mat a(n,n);
	a.A[0][0] = A;
	a.A[0][1] = B;
	a.A[1][0] = C;
	a.A[1][1] = D;
	mat v(n,1);
	v.A[0][0] = S;
	v.A[1][0] = T;
	auto u = a.pow(N) * v;
	cout<<u.A[0][0].val()<<" "<<u.A[1][0].val()<<endl;
}
0