#include <bits/stdc++.h>
using namespace std;
const int maxn = 100000;
struct HashTree {
  int w;
  vector<unsigned long long> vecHash;
  vector<int> vecNode;
  vector<unsigned long long> lv, lv_sum;
  unsigned long long seed;
  unsigned long long mod;
  HashTree(int n, unsigned long long seed, unsigned long long mod)
      : seed(seed), mod(mod) {
    for (w = 1; w <= n; w *= 2)
      ;
    ;
    vecHash.resize(w * 2 + 1);
    vecNode.resize(w * 2 + 1);
    lv.resize(w + 1);
    lv_sum.resize(w + 1);
    lv_sum[0] = lv[0] = 1;
    for (int i = 1; i <= w; i++) {
      lv[i] = (lv[i - 1] * seed) % mod;
      lv_sum[i] = (lv[i] + lv_sum[i - 1]) % mod;
    }
  }
  void update(int l, int r, int val, int lm = 0, int rm = -1, int pos = 1) {
    if (rm == -1) rm = w - 1;
    vecHash[pos] %= mod;
    int mid = (lm + rm) / 2;
    if (r < lm || rm < l)
      return;
    else if (l <= lm && rm <= r)
      vecNode[pos] = val;
    else {
      if (vecNode[pos] != -1) {
        vecNode[pos * 2] = vecNode[pos * 2 + 1] = vecNode[pos];
        vecHash[pos * 2] = vecHash[pos * 2 + 1] =
            (vecNode[pos] * lv_sum[mid - lm]) % mod;
      }
      update(l, r, val, lm, mid, pos * 2);
      update(l, r, val, mid + 1, rm, pos * 2 + 1);
      if (vecNode[pos * 2] == vecNode[pos * 2 + 1])
        vecNode[pos] = vecNode[pos * 2];
      else
        vecNode[pos] = -1;
    }
    if (vecNode[pos] != -1)
      vecHash[pos] = vecNode[pos] * lv_sum[rm - lm];
    else
      vecHash[pos] = vecHash[pos * 2] * lv[rm - mid] + vecHash[pos * 2 + 1];
    vecHash[pos] %= mod;
  }
  unsigned long long get(int l, int r, int lm = 0, int rm = -1, int pos = 1) {
    if (rm == -1) rm = w - 1;
    int mid = (lm + rm) / 2;
    if (r < lm || rm < l) return 0;
    if (vecNode[pos] != -1) {
      int len = min(r, rm) - max(l, lm);
      return (vecNode[pos] * lv_sum[len]) % mod;
    } else if (l <= lm && rm <= r) {
      return vecHash[pos];
    } else {
      int rlen = max(0, 1 + min(rm, r) - max(mid + 1, l));
      unsigned long long lret = get(l, r, lm, mid, pos * 2);
      unsigned long long rret = get(l, r, mid + 1, rm, pos * 2 + 1);
      return (lret * lv[rlen] + rret) % mod;
      ;
    }
  }
};
char buff[maxn + 2];
int main() {
  int n, m, k;
  scanf("%d %d %d", &n, &m, &k);
  int q = m + k;
  scanf("%s", buff);
  HashTree tree(n + 1, 5507, 1000000007);
  HashTree tree2(n + 1, 5507, 1000000207);
  HashTree tree3(n + 1, 5507, 1000001273);
  for (int i = 0; i < n; i++) {
    tree.update(i, i, buff[i] - '0');
    tree2.update(i, i, buff[i] - '0');
    tree3.update(i, i, buff[i] - '0');
  }
  for (int i = 0; i < q; i++) {
    int op, l, r, val;
    scanf("%d %d %d %d", &op, &l, &r, &val);
    l--;
    r--;
    if (op == 1) {
      tree.update(l, r, val);
      tree2.update(l, r, val);
      tree3.update(l, r, val);
    } else {
      if (val == (r - l + 1)) {
        printf("YES\n");
        continue;
      }
      unsigned long long lHash = tree.get(l, r - val);
      unsigned long long rHash = tree.get(l + val, r);
      if (lHash == rHash && tree2.get(l, r - val) == tree2.get(l + val, r) &&
          tree3.get(l, r - val) == tree3.get(l + val, r)) {
        printf("YES\n");
      } else {
        printf("NO\n");
      }
    }
  }
  return 0;
}
