#include <bits/stdc++.h>
const int mod1 = 573292817, mod2 = 1e9 + 7, base1 = 233, base2 = 2333,
          maxn = 100010, maxt = maxn << 3;
using namespace std;
int n, m, k;
char s[maxn];
long long pow1[maxn], pow2[maxn], sp1[maxn], sp2[maxn];
struct node {
  long long v1, v2;
  int cov, len;
};
struct Segment_Tree {
  node t[maxt];
  void add_cov(int p, int c) {
    t[p].cov = c;
    t[p].v1 = c * sp1[t[p].len - 1] % mod1;
    t[p].v2 = c * sp2[t[p].len - 1] % mod2;
  }
  void down(int p) {
    if (t[p].cov != -1)
      add_cov((p << 1), t[p].cov), add_cov(((p << 1) | 1), t[p].cov),
          t[p].cov = -1;
  }
  node connect(node a, node b) {
    int len = a.len + b.len;
    long long v1 = (a.v1 * pow1[b.len] + b.v1) % mod1;
    long long v2 = (a.v2 * pow2[b.len] + b.v2) % mod2;
    return (node){v1, v2, -1, len};
  }
  void update(int p) {
    t[p].v1 = (t[(p << 1)].v1 * pow1[t[((p << 1) | 1)].len] % mod1 +
               t[((p << 1) | 1)].v1) %
              mod1;
    t[p].v2 = (t[(p << 1)].v2 * pow2[t[((p << 1) | 1)].len] % mod2 +
               t[((p << 1) | 1)].v2) %
              mod2;
  }
  void build(int p, int l, int r) {
    t[p].len = r - l + 1, t[p].cov = -1;
    if (l == r) {
      t[p].v1 = t[p].v2 = s[l] - '0';
      return;
    }
    build((p << 1), l, ((l + r) >> 1)),
        build(((p << 1) | 1), ((l + r) >> 1) + 1, r);
    update(p);
  }
  void modify(int p, int l, int r, int a, int b, int c) {
    if (l == a && r == b) {
      add_cov(p, c);
      return;
    }
    down(p);
    if (b <= ((l + r) >> 1))
      modify((p << 1), l, ((l + r) >> 1), a, b, c);
    else if (a > ((l + r) >> 1))
      modify(((p << 1) | 1), ((l + r) >> 1) + 1, r, a, b, c);
    else
      modify((p << 1), l, ((l + r) >> 1), a, ((l + r) >> 1), c),
          modify(((p << 1) | 1), ((l + r) >> 1) + 1, r, ((l + r) >> 1) + 1, b,
                 c);
    update(p);
  }
  node query(int p, int l, int r, int a, int b) {
    if (l == a && r == b) {
      return t[p];
    }
    down(p);
    node ans;
    if (b <= ((l + r) >> 1))
      ans = query((p << 1), l, ((l + r) >> 1), a, b);
    else if (a > ((l + r) >> 1))
      ans = query(((p << 1) | 1), ((l + r) >> 1) + 1, r, a, b);
    else
      ans = connect(
          query((p << 1), l, ((l + r) >> 1), a, ((l + r) >> 1)),
          query(((p << 1) | 1), ((l + r) >> 1) + 1, r, ((l + r) >> 1) + 1, b));
    return ans;
  }
  pair<long long, long long> query(int a, int b) {
    node ans = query(1, 1, n, a, b);
    return make_pair(ans.v1, ans.v2);
  }
} T;
void init() {
  scanf("%d%d%d%s", &n, &m, &k, s + 1), m = m + k;
  pow1[0] = pow2[0] = sp1[0] = sp2[0] = 1;
  for (int i = 1; i <= n + 5; i++) {
    pow1[i] = pow1[i - 1] * base1 % mod1;
    pow2[i] = pow2[i - 1] * base2 % mod2;
    sp1[i] = (sp1[i - 1] + pow1[i]) % mod1;
    sp2[i] = (sp2[i - 1] + pow2[i]) % mod2;
  }
  T.build(1, 1, n);
}
void work() {
  for (int i = 1, op, a, b, c; i <= m; i++) {
    scanf("%d%d%d%d", &op, &a, &b, &c);
    if (op == 1)
      T.modify(1, 1, n, a, b, c);
    else {
      if (b - a + 1 <= c) {
        puts("YES");
        continue;
      } else
        puts(T.query(a, b - c) == T.query(a + c, b) ? "YES" : "NO");
    }
  }
}
int main() {
  init(), work();
  return 0;
}
