#include <cstdio> #include <algorithm> #include <vector> #include <numeric> #include <cassert> #include <cmath> #include <map> #include <unordered_map> #include <set> #include <random> #include <vector> #include <iostream> #include <string> #include <complex> #include <functional> #include <tuple> #define FOR(k,a,b) for(int k(a); k < (b); ++k) #define REP(k,a) for(int k=0; k < (a); ++k) #define ABS(a) ((a)>0?(a):-(a)) using namespace std; typedef long long LL; typedef unsigned int uint; typedef pair<int, int> PII; typedef vector<int> VI; typedef vector<LL> VL; typedef vector<int>::const_iterator VITER; typedef vector<double> VD; typedef vector<PII> VPII; typedef vector<VPII> VVPII; typedef vector<VI> VVI; typedef vector<VD> VVD; typedef vector<bool > VB; typedef vector<VB> VVB; typedef tuple<LL, LL, LL, LL> L4; int mod, sqrtmod, sqsqrtmod; const double PI = 2 * acos(0.0); vector<int> factorial, inverseFactorial; typedef complex<long double> base; LL powmod(LL a, int p) { LL res = 1; LL act = a; while (p) { if (p & 1) { res *= act; res %= mod; } act *= act; act %= mod; p >>= 1; } return res; } LL inverse(LL a) { return powmod(a, mod - 2); } void fft(vector<base> & a, bool invert) { int n = (int)a.size(); for (int i = 1, j = 0; i<n; ++i) { int bit = n >> 1; for (; j >= bit; bit >>= 1) j -= bit; j += bit; if (i < j) swap(a[i], a[j]); } for (int len = 2; len <= n; len <<= 1) { long double ang = 2 * PI / len * (invert ? -1 : 1); base wlen(cos(ang), sin(ang)); for (int i = 0; i<n; i += len) { base w(1); for (int j = 0; j<len / 2; ++j) { base u = a[i + j], v = a[i + j + len / 2] * w; a[i + j] = u + v; a[i + j + len / 2] = u - v; w *= wlen; } } } if (invert) for (int i = 0; i<n; ++i) a[i] /= n; } VI bfmultiply(VITER astart, VITER aend, VITER bstart, VITER bend) { int n = distance(astart, aend); assert(n == distance(bstart, bend)); VI res(2*n); REP(i,n) REP(j,n) { res[i + j] = (res[i + j] + *(astart + i) * 1ll * *(bstart + j)) % mod; } return res; } VI multiply(VITER astart, VITER aend, VITER bstart, VITER bend) { int n = distance(astart,aend); assert(n == distance(bstart, bend)); vector<base> fa1(2*n), fa2(2*n), fb1(2*n), fb2(2*n); REP(i,n) { fa2[i] = *astart % sqrtmod; fa1[i] = *astart / sqrtmod; fb2[i] = *bstart % sqrtmod; fb1[i] = *bstart / sqrtmod; ++astart, ++bstart; } fft(fa1, false), fft(fa2, false), fft(fb1, false), fft(fb2, false); vector<base> cfa1(fa1), cfa2(fa2); for (size_t i = 0; i < 2*n; ++i) { fa1[i] *= fb1[i];//*sqsq cfa1[i] *= fb2[i];//sq fa2[i] *= fb1[i];//sq cfa2[i] *= fb2[i];//1 } fft(fa1, true); fft(cfa1, true); fft(fa2, true); fft(cfa2, true); VI res(2*n); for (size_t i = 0; i < 2*n; ++i) { res[i] = LL(cfa2[i].real() + 0.5)%mod; res[i] = (res[i] + (LL(fa2[i].real() + 0.5)%mod *1ll* sqrtmod))%mod; res[i] = (res[i] + (LL(cfa1[i].real() + 0.5)%mod * 1ll * sqrtmod)) % mod; res[i] = (res[i] + (LL(fa1[i].real() + 0.5) % mod *1ll * sqsqrtmod)) % mod; } return res; } VI bfASolver(VL f, int n) { VI res(n); res[0] = f[0]; LL act; FOR(i, 1, n) { act = 1; if (i % 10000 == 0) fprintf(stderr, "sss : %d %d\n", n,i); REP(j, i) { f[i] = (f[i] + mod - (res[j] *1ll* act) % mod)%mod; act = (mod-((i - j)*1ll*act)%mod)%mod; } res[i] = i&1 ? mod-f[i] : f[i]; res[i] %= mod; res[i] = (res[i] * 1ll * inverseFactorial[i]) % mod; } return res; } L4 mult(const L4& a, const L4& b) { return make_tuple( (get<0>(a)*get<0>(b) + get<1>(a)*get<2>(b)) % mod, (get<0>(a)*get<1>(b) + get<1>(a)*get<3>(b)) % mod, (get<2>(a)*get<0>(b) + get<3>(a)*get<2>(b)) % mod, (get<2>(a)*get<1>(b) + get<3>(a)*get<3>(b)) % mod); } int binom(int a, int b) { if (b > a) return 0; int res = factorial[a]; res = (res * 1ll * inverseFactorial[b]) % mod; res = (res * 1ll * inverseFactorial[a-b]) % mod; return res; } int main(int argc, char** argv) { #ifdef HOME freopen("in.txt", "rb", stdin); //freopen("BINOMSUM_3.in", "rb", stdin); freopen("out.txt", "wb", stdout); #endif int K, A, P, Q; scanf("%d %d %d %d", &K, &A, &P, &Q); mod = P; sqrtmod = sqrt(0.5+mod); sqsqrtmod = sqrtmod * sqrtmod; int MX = 10600001; factorial.resize(MX); inverseFactorial.resize(MX); factorial[0] = inverseFactorial[0] = 1; FOR(i, 1, MX) factorial[i] = (factorial[i - 1] * 1ll * i) % mod; inverseFactorial[MX-1] = inverse(factorial[MX-1]); for(int i = MX-2; i;--i) { inverseFactorial[i] = (inverseFactorial[i + 1] * 1ll * (i + 1)) % mod; } vector<LL> fd(K + 1); int pi = 0, api = A%P; for(int i = -1; i>= -K;--i) { if (--pi < 0) pi += P; if (--api < 0) api += P; L4 act = make_tuple(1, 0, 0, 1); L4 pp = make_tuple(A,(pi*1ll*A)%P,1,0); int pw = K - 2; while(pw) { if(pw&1) act = mult(act, pp); pp = mult(pp, pp); pw >>= 1; } fd[-i] = (get<2>(act)*(api) +get<3>(act))%P; } int kk = (K - 1) / 2 + 1; vector<int> aa(kk), bb(2*kk); REP(i,2*kk) { bb[i] = inverseFactorial[i]; } fd.erase(fd.begin()); //VI BFa = bfASolver(fd, kk); aa[0] = fd[0]; FOR(i, 1, kk) { fd[i] -= aa[0]; if (fd[i] < 0) fd[i] += mod; } FOR(i,1,kk) { fd[i] = (fd[i] * 1ll * inverseFactorial[i]) % mod; if (fd[i] < 0) fd[i] += mod; } for(int i = 1;i < kk; ++i) { //process already calculate elements if (i > 1) { fd[i] = fd[i] + (aa[i - 1] * 1ll * bb[1]) % P; if (fd[i] >= P) fd[i] -= P; } if (i > 2) { fd[i] = fd[i] + (aa[i - 2] * 1ll * bb[2]) % P; if (fd[i] >= P) fd[i] -= P; } int ii = i - 1; int start = 3; int len = 2; while (ii && (i-2)%len == 0) { // (ii-len,ii]x[start, start+len) if (i - len < 1) break; //VI res = multiply(aa.begin() + ii - len, aa.begin() + ii, bb.begin() + start, bb.begin() + start + len); VI res = multiply(aa.begin() + ii - len, aa.begin() + ii, bb.begin() + start, bb.begin() + start + len); REP(j,res.size()) { if (i + j < kk) { fd[i + j] = fd[i + j] + res[j]; if (fd[i + j] < 0) fd[i + j] += P; if (fd[i + j] >= P) fd[i + j] -= P; } } start += len; len *= 2; } //calculate next aa[i] = fd[i] ? mod-fd[i] : 0; } FOR(i,1, aa.size()) { if ((i & 1)==0 && aa[i]) { aa[i] = mod - aa[i]; } } //if(aa == BFa) //{ // int alma = 42; //} //aa = BFa; // REP(q,Q) { int L, D, T, ans = 0; scanf("%d %d %d", &L, &D, &T); vector<int> QL(kk, 1);//, QLInv(kk, 1); FOR(i, 1, kk) { QL[i] = (QL[i - 1] * 1ll * (L + i)) % P; //QLInv[i] = inverse(QL[i]); } REP(i,kk) { int inc = (aa[i] * 1ll * QL[i])%P; int binomDiff = (binom(D + T + i, L + i + 1) - binom(D + i, L + i + 1) + P) % P; ans = (ans + inc * 1ll * binomDiff) % P; } ans = (ans * 1ll * A) % mod; printf("%d\n", ans); } return 0; }