#include #include #include #include #include #include using namespace std; const int MOD = (int)1e9 + 7; const int Tmax = 1000033; const int Nmax = 100333; int inv[Nmax], lp[Nmax]; vector primes; int answer[Tmax]; int d[Nmax], C[Tmax], D[Tmax]; stack lists[Nmax]; int A, B, M; struct Segm { Segm * l, * r; int prod; Segm(int sum):l(NULL),r(NULL),prod(sum){}; Segm(Segm *l,Segm *r):l(l),r(r),prod(1){ if (l) prod = (prod * 1ll * l->prod) % MOD; if (r) prod = (prod * 1ll * r -> prod) % MOD; }; int calc() { int res = 1; if (l) res = (res * 1ll * l->prod) % MOD; if (r) res = (res * 1ll * r -> prod) % MOD; return res; } }; Segm *Tree[Nmax]; Segm *build(int l,int r) { if (l == r) return new Segm(1); int m = (l + r)/2; return new Segm( build(l,m), build(m+1,r)); } int get(Segm * v, int tl,int tr , int l,int r) { if (l > r || !v) return 1; if (tl == l && tr == r) return v->prod; int m =(tl+tr)/2; return get(v->l,tl,m,l,min(r,m)) * 1ll * get(v->r,m+1,tr,max(m+1,l),r) % MOD; } Segm *update(Segm *v,int tl,int tr,int num,int x) { if (tl == tr) return new Segm(x); int m = (tl + tr) / 2; if (num <= m) return new Segm( update(v->l,tl,m,num,x) , v->r); else return new Segm( v->l , update(v->r , m+1,tr,num,x) ); } void inc(int N) { Tree[N] = Tree[N - 1]; for (int x = N; x > 1;) { int prime = lp[x]; int cnt = 0; while (x % prime == 0) x /= prime, cnt ++; while (!lists[prime].empty() && cnt > 0) { int idx = lists[prime].top(); if (d[idx] % prime != 0) { lists[prime].pop(); continue; } d[idx] /= prime; cnt --; Tree[N] = update(Tree[N], 1, M, idx, d[idx]); } lists[prime].push(N); } d[N] = N; Tree[N] = update(Tree[N], 1, M, N, N); /* for (int i = 1; i <= N; i ++) cerr << get(Tree[N], 1, M, i, i) << " "; cerr << endl;*/ } int main() { int T; cin >> T; assert(1 <= T && T <= 1e6); scanf("%d %d", &C[1], &D[1]); assert(D[1] <= C[1] && D[1] >= 1); scanf("%d %d %d", &A, &B, &M); assert(A >= 0 && A < M); assert(B >= 0 && B < M); assert(M <= 1e5 && M >= C[1]); D[1] = (C[1] + D[1] - 1) % C[1]; C[1] = (C[1] + M - 1) % M; for (int i = 2; i <= T; i ++) { scanf("%d", &C[i]); assert(C[i] >= 0 && C[i] < M); } for (int i = 2; i <= T; i ++) { scanf("%d", &D[i]); assert(D[i] >= 0 && D[i] < M); } int Answer = 0; for (int i = 2; i < Nmax; i ++) { if (!lp[i]) { primes.push_back(i); lp[i] = i; } for (int j = 0; j < primes.size() && primes[j] <= lp[i] && i * 1ll * primes[j] < Nmax; j ++) { lp[primes[j] * i] = primes[j]; } } Tree[1] = build(1, M); int N = 1; d[1] = 1; while (N < M) { inc(++N); } for (int i = 1; i <= T; i ++) { int n = 1 + (Answer * 1ll * A + C[i]) % M; int k = 1 + (Answer * 1ll * B + D[i]) % n; assert(k >= 1 && k <= n && n <= M); Answer = get(Tree[n], 1, M, n - k + 1, n); printf("%d\n", Answer); } cin.get();cin.get(); return 0; }