#include <bits/stdc++.h>
using namespace std;
long long ten[100000 + 1][4];
long long ten_inv[100000 + 1][4];
string s;
long long seg_tree[4 * 100000][4];
long long lazy[4 * 100000];
long long MOD[] = {1000000000 + 7, 1000000000 + 9, 1000000000 + 21,
                   1000000000 + 33};
long long mod_pow(long long base, long long exp, long long m) {
  if (exp == 0) return 1;
  if (exp & 1)
    return (base * mod_pow(base, exp - 1, m)) % m;
  else
    return mod_pow((base * base) % m, exp / 2, m);
}
long long concat(long long lft, long long rght, int r_len, int v) {
  return (lft * (ten[r_len][v] + 1) + rght) % MOD[v];
}
void build(int L, int R, int node) {
  if (L == R) {
    for (int v = 0; v < 4; v++) seg_tree[node][v] = s[L] - '0';
    return;
  }
  build(L, (L + R) / 2, 2 * node);
  build((L + R) / 2 + 1, R, 2 * node + 1);
  for (int v = 0; v < 4; v++)
    seg_tree[node][v] = concat(seg_tree[2 * node][v], seg_tree[2 * node + 1][v],
                               R - (L + R) / 2, v);
}
long long series(long long period, long long len, int v) {
  return (ten[len][v] * ten_inv[period][v]) % MOD[v];
}
void digit_set(int L, int R, long long c, int node) {
  for (int v = 0; v < 4; v++)
    seg_tree[node][v] = (c * series(1, R - L + 1, v)) % MOD[v];
  if (L != R) {
    lazy[2 * node] = c;
    lazy[2 * node + 1] = c;
  }
  lazy[node] = -1;
}
void update(int L, int R, int l, int r, int c, int node) {
  if (lazy[node] != -1) digit_set(L, R, lazy[node], node);
  if (L > R || R < l || L > r) return;
  if (l <= L && R <= r) {
    digit_set(L, R, c, node);
    return;
  }
  update(L, (L + R) / 2, l, r, c, 2 * node);
  update((L + R) / 2 + 1, R, l, r, c, 2 * node + 1);
  for (int v = 0; v < 4; v++)
    seg_tree[node][v] = concat(seg_tree[2 * node][v], seg_tree[2 * node + 1][v],
                               R - (L + R) / 2, v);
}
long long query(int L, int R, int l, int r, int node, int v) {
  if (lazy[node] != -1) digit_set(L, R, lazy[node], node);
  if (L > R || R < l || L > r) return 0;
  if (l <= L && R <= r)
    return seg_tree[node][v];
  else if (r <= (L + R) / 2)
    return query(L, (L + R) / 2, l, r, 2 * node, v);
  else
    return concat(query(L, (L + R) / 2, l, r, 2 * node, v),
                  query((L + R) / 2 + 1, R, l, r, 2 * node + 1, v),
                  min(r, R) - (L + R) / 2, v);
}
bool is_period(int n, int l, int r, int x) {
  if (x > (r - l + 1) / 2) {
    for (int v = 0; v < 4; v++)
      if (query(0, n - 1, l, l + (r - l + 1) - x - 1, 1, v) !=
          query(0, n - 1, r - ((r - l + 1) - x) + 1, r, 1, v))
        return false;
    return true;
  }
  r = l + x * ((r - l + 1) / x) - 1;
  for (int v = 0; v < 4; v++)
    if (query(0, n - 1, l, r, 1, v) !=
        (query(0, n - 1, l, l + x - 1, 1, v) * series(x, r - l + 1, v)) %
            MOD[v])
      return false;
  return true;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  for (int v = 0; v < 4; v++) ten[0][v] = 0;
  for (int i = 1; i <= 100000; i++)
    for (int v = 0; v < 4; v++)
      ten[i][v] = ((ten[i - 1][v] + 1LL) * 10LL - 1LL) % MOD[v];
  for (int v = 0; v < 4; v++)
    for (int i = 0; i <= 100000; i++)
      ten_inv[i][v] = mod_pow(ten[i][v], MOD[v] - 2, MOD[v]);
  int n, m, k;
  cin >> n >> m >> k;
  cin >> s;
  build(0, n - 1, 1);
  memset(lazy, -1, sizeof lazy);
  for (int q = 0; q < m + k; q++) {
    int t, l, r, x;
    cin >> t >> l >> r >> x;
    l--, r--;
    if (t == 1)
      update(0, n - 1, l, r, x, 1);
    else
      cout << (is_period(n, l, r, x) ? "YES" : "NO") << '\n';
  }
  cout << flush;
  return 0;
}
