#include #define endl '\n' using namespace std; const int MAXN = (1 << 18); const int mod = (int)1e9 + 7; int n, m; int64_t A, B; int64_t a[MAXN], pwA[MAXN]; struct node { int64_t ans, len; node() {ans = 0;len = 0;} node(int val) { ans = val; len = 1; } }; node temp, broken; node merge(node l, node r) { temp.len = l.len + r.len; temp.ans = (r.ans * pwA[l.len] + l.ans) % mod; return temp; } struct segment_tree { node tr[4 * MAXN]; void init(int l, int r, int idx) { if(l == r) { tr[idx] = node(a[l]); return; } int mid = (l + r) >> 1; init(l, mid, 2 * idx + 1); init(mid + 1, r, 2 * idx + 2); tr[idx] = merge(tr[2 * idx + 1], tr[2 * idx + 2]); } void update(int pos, int64_t val, int l, int r, int idx) { if(l > pos || r < pos) return; if(l == r && l == pos) { tr[idx] = node(val); return; } int mid = (l + r) >> 1; update(pos, val, l, mid, 2 * idx + 1); update(pos, val, mid + 1, r, 2 * idx + 2); tr[idx] = merge(tr[2 * idx + 1], tr[2 * idx + 2]); } node query(int qL, int qR, int l, int r, int idx) { if(l > qR || r < qL) return broken; if(qL <= l && r <= qR) return tr[idx]; int mid = (l + r) >> 1; return merge(query(qL, qR, l, mid, 2 * idx + 1), query(qL, qR, mid + 1, r, 2 * idx + 2)); } }; int64_t power(int64_t x, int64_t y, int64_t m) { if (y == 0) return 1; int64_t p = power(x, y/2, m) % m; p = (p * p) % m; return (y%2 == 0)? p : (x * p) % m; } int64_t mod_inv(int64_t a, int64_t m) { return power(a, m-2, m); } void read() { cin >> n >> A >> B >> m; for(int i = 0; i < n; i++) cin >> a[i]; } segment_tree t; void query(node p) { int64_t ret = (p.ans * A) % mod; if(ret == 0) cout << "Yes" << endl; else cout << "No" << endl; } void solve() { B = ((mod - B) * mod_inv(A, mod)) % mod; pwA[0] = 1; for(int i = 1; i <= n; i++) pwA[i] = ((B) * pwA[i - 1]) % mod; t.init(0, n - 1, 0); for(int i = 0; i < m; i++) { int type, l, r; cin >> type; cin >> l >> r; if(type == 2) query(t.query(l, r, 0, n - 1, 0)); else t.update(l, r, 0, n - 1, 0); } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); read(); solve(); return 0; }