#include <bits/stdc++.h>
unsigned long long val(int i) { return i + 1; }
unsigned long long pot1[100001], pot2[100001], prec1[10][100001],
    prec2[10][100001];
int v[100000];
struct Node {
  unsigned long long h1, h2;
  int flag;
  bool valid;
  int sz;
  Node() {
    sz = h1 = h2 = 0;
    flag = -1;
    valid = true;
  }
  Node(unsigned long long a, unsigned long long b, int c) {
    h1 = a;
    h2 = b;
    sz = c;
    flag = -1;
    valid = true;
  }
  Node(unsigned long long a, unsigned long long b, int c, bool d) {
    h1 = a;
    h2 = b;
    sz = c;
    valid = d;
    flag = -1;
  }
  void set(int c) { flag = c; }
  void reset() { flag = -1; }
  void update(int c) {
    if (c == -1) return;
    h1 = prec1[c][sz];
    h2 = prec2[c][sz];
  }
  bool operator!=(const Node& n) { return h1 != n.h1 || h2 != n.h2; }
};
Node st[400000];
inline int left(int i) { return 2 * i + 1; }
inline int right(int i) { return 2 * i + 2; }
void initialize(int r, int beg, int end) {
  if (beg == end) {
    st[r] = Node(val(v[beg]), val(v[beg]), 1);
  } else {
    int h = (beg + end) / 2;
    initialize(left(r), beg, h);
    initialize(right(r), h + 1, end);
    st[r] = Node(
        (st[left(r)].h1 * pot1[st[right(r)].sz] + st[right(r)].h1) % 1000000009,
        (st[left(r)].h2 * pot2[st[right(r)].sz] + st[right(r)].h2) % 1000000007,
        st[left(r)].sz + st[right(r)].sz);
  }
}
void update(int r, int beg, int end, int qbeg, int qend, char c) {
  if (end < qbeg || beg > qend) {
    if (st[r].flag != -1) {
      st[r].update(st[r].flag);
      if (beg != end) {
        st[2 * r + 1].set(st[r].flag);
        st[2 * r + 2].set(st[r].flag);
      }
      st[r].reset();
    }
    return;
  }
  if (beg >= qbeg && end <= qend) {
    st[r].update(c);
    if (beg != end) {
      st[left(r)].set(c);
      st[right(r)].set(c);
    }
    st[r].reset();
  } else {
    int h = (beg + end) / 2;
    if (st[r].flag != -1) {
      st[r].update(st[r].flag);
      st[2 * r + 1].set(st[r].flag);
      st[2 * r + 2].set(st[r].flag);
      st[r].reset();
    }
    update(left(r), beg, h, qbeg, qend, c);
    update(right(r), h + 1, end, qbeg, qend, c);
    st[r] = Node(
        (st[left(r)].h1 * pot1[st[right(r)].sz] + st[right(r)].h1) % 1000000009,
        (st[left(r)].h2 * pot2[st[right(r)].sz] + st[right(r)].h2) % 1000000007,
        st[right(r)].sz + st[left(r)].sz);
  }
}
Node query(int r, int beg, int end, int qbeg, int qend) {
  if (end < qbeg || beg > qend) return Node(0, 0, false);
  if (beg >= qbeg && end <= qend) {
    if (st[r].flag != -1) {
      st[r].update(st[r].flag);
      if (beg != end) {
        st[left(r)].set(st[r].flag);
        st[right(r)].set(st[r].flag);
      }
      st[r].reset();
    }
    return st[r];
  } else {
    if (st[r].flag != -1) {
      st[r].update(st[r].flag);
      st[left(r)].set(st[r].flag);
      st[right(r)].set(st[r].flag);
      st[r].reset();
    }
    Node le = query(left(r), beg, (beg + end) / 2, qbeg, qend);
    Node ri = query(right(r), (beg + end) / 2 + 1, end, qbeg, qend);
    if (le.valid && ri.valid)
      return Node((le.h1 * pot1[ri.sz] + ri.h1) % 1000000009,
                  (le.h2 * pot2[ri.sz] + ri.h2) % 1000000007, le.sz + ri.sz);
    else if (le.valid)
      return le;
    else
      return ri;
  }
}
bool qquery(int r, int beg, int end, int qbeg, int qend, int d) {
  int sz = qend - qbeg + 1;
  if (sz <= d) return true;
  if (qbeg > qend) return 0;
  int sobra = sz % d;
  if (sobra) {
    if (query(r, beg, end, qbeg, qbeg + sobra - 1) !=
        query(r, beg, end, qend - sobra + 1, qend))
      return false;
  }
  qend -= sobra;
  sz = qend - qbeg + 1;
  int n = sz / d;
  if (sz == d) return true;
  if (n & 1) {
    int b0 = qbeg, b1 = qbeg + n / 2 * d, b2 = qbeg + (n / 2 + 1) * d;
    int e0 = b1 - 1, e1 = b2 - 1, e2 = qend;
    if (query(r, beg, end, b0, e0) != query(r, beg, end, b2, e2) ||
        query(r, beg, end, b0, b0 + d - 1) != query(r, beg, end, b1, e1))
      return false;
    return qquery(r, beg, end, b0, e0, d);
  } else {
    int b0 = qbeg, b1 = qbeg + (n + 1) / 2 * d;
    int e0 = b1 - 1, e1 = qend;
    if (query(r, beg, end, b0, e0) != query(r, beg, end, b1, e1)) return false;
    return qquery(r, beg, end, b0, e0, d);
  }
}
void precalc() {
  pot1[0] = 1;
  pot2[0] = 1;
  for (int i = 1; i <= 100000; i++) {
    pot1[i] = (pot1[i - 1] * 33) % 1000000009;
    pot2[i] = (pot2[i - 1] * 33) % 1000000007;
  }
  for (int i = 0; i < 10; i++) {
    prec1[i][0] = 0;
    prec2[i][0] = 0;
    for (int j = 1; j <= 100000; j++) {
      prec1[i][j] = (prec1[i][j - 1] * 33 + val(i)) % 1000000009;
      prec2[i][j] = (prec2[i][j - 1] * 33 + val(i)) % 1000000007;
    }
  }
}
int main(void) {
  int n, m, k;
  char s[100001];
  precalc();
  scanf("%d%d%d", &n, &m, &k);
  scanf("%s", s);
  for (int i = 0; i < n; i++) {
    v[i] = s[i] - '0';
  }
  initialize(0, 0, n - 1);
  for (int i = 0; i < m + k; i++) {
    int cmd;
    int l, r, x;
    scanf("%d%d%d%d", &cmd, &l, &r, &x);
    if (cmd == 1) {
      l--;
      r--;
      update(0, 0, n - 1, l, r, x);
    } else {
      l--;
      r--;
      printf("%s\n", qquery(0, 0, n - 1, l, r, x) ? "YES" : "NO");
    }
  }
}
