#include <bits/stdc++.h>
using namespace std;
int n, m, k, lens;
char s[100010];
class HashTree {
 public:
  int mod, p;
  long long powp[100010], sump[100010];
  void getpowp() {
    powp[0] = 1;
    sump[0] = 1;
    for (int i = 1; i < 100010; i++) {
      powp[i] = powp[i - 1] * p;
      if (powp[i] >= mod) powp[i] %= mod;
      sump[i] = sump[i - 1] + powp[i];
      if (sump[i] >= mod) sump[i] %= mod;
    }
  }
  long long v[100010 << 2];
  int len[100010 << 2];
  char lazy[100010 << 2];
  void plant(int id, int l, int r) {
    lazy[id] = '\0';
    if (l == r) {
      v[id] = s[l];
      len[id] = 1;
      return;
    }
    int mid = (l + r) >> 1;
    plant(id << 1, l, mid);
    plant(id << 1 | 1, mid + 1, r);
    len[id] = len[id << 1] + len[id << 1 | 1];
    v[id] = v[id << 1] * powp[len[id << 1 | 1]] + v[id << 1 | 1];
    if (v[id] >= mod) v[id] %= mod;
  }
  void pushdown(int id) {
    if (lazy[id] != '\0') {
      lazy[id << 1] = lazy[id << 1 | 1] = lazy[id];
      v[id << 1] = lazy[id] * sump[len[id << 1] - 1];
      if (v[id << 1] >= mod) v[id << 1] %= mod;
      v[id << 1 | 1] = lazy[id] * sump[len[id << 1 | 1] - 1];
      if (v[id << 1 | 1] >= mod) v[id << 1 | 1] %= mod;
      lazy[id] = '\0';
    }
  }
  void update(int id, int ql, int qr, int l, int r, char c) {
    if (ql == l && qr == r) {
      lazy[id] = c;
      v[id] = c * sump[len[id] - 1];
      if (v[id] >= mod) v[id] %= mod;
      return;
    }
    pushdown(id);
    int mid = (l + r) >> 1;
    if (qr <= mid)
      update(id << 1, ql, qr, l, mid, c);
    else if (mid < ql)
      update(id << 1 | 1, ql, qr, mid + 1, r, c);
    else
      update(id << 1, ql, mid, l, mid, c),
          update(id << 1 | 1, mid + 1, qr, mid + 1, r, c);
    v[id] = v[id << 1] * powp[len[id << 1 | 1]] + v[id << 1 | 1];
    if (v[id] >= mod) v[id] %= mod;
  }
  long long query(int id, int ql, int qr, int l, int r) {
    if (ql == l && qr == r) {
      return v[id];
    }
    pushdown(id);
    int mid = (l + r) >> 1;
    if (qr <= mid)
      return query(id << 1, ql, qr, l, mid);
    else if (mid < ql)
      return query(id << 1 | 1, ql, qr, mid + 1, r);
    else {
      long long t1 = query(id << 1, ql, mid, l, mid);
      long long t2 = query(id << 1 | 1, mid + 1, qr, mid + 1, r);
      long long t = t1 * powp[qr - (mid + 1) + 1] + t2;
      if (t >= mod) t %= mod;
      return t;
    }
  }
} tree1, tree2;
bool equal(int l1, int r1, int l2, int r2) {
  if (tree1.query(1, l1, r1, 0, lens - 1) !=
      tree1.query(1, l2, r2, 0, lens - 1))
    return false;
  if (tree2.query(1, l1, r1, 0, lens - 1) !=
      tree2.query(1, l2, r2, 0, lens - 1))
    return false;
  return true;
}
bool judge(int l, int r, int d) {
  if (r - l + 1 == d) return true;
  int l2 = l + d, r2 = r;
  int len = r2 - l2 + 1;
  int l1 = l, r1 = l1 + len - 1;
  return equal(l1, r1, l2, r2);
}
int main() {
  tree1.mod = 1e9 + 7, tree1.p = 799817, tree1.getpowp();
  tree2.mod = 1e9 + 9, tree2.p = 451309, tree2.getpowp();
  scanf("%d%d%d", &n, &m, &k);
  scanf("%s", s);
  lens = (int)strlen(s);
  tree1.plant(1, 0, lens - 1), tree2.plant(1, 0, lens - 1);
  for (int i = 1; i <= m + k; i++) {
    int ty, l, r;
    scanf("%d%d%d", &ty, &l, &r);
    l--, r--;
    if (ty == 1) {
      char c[5];
      scanf("%s", c);
      tree1.update(1, l, r, 0, lens - 1, c[0]);
      tree2.update(1, l, r, 0, lens - 1, c[0]);
    } else {
      int d;
      scanf("%d", &d);
      printf("%s\n", judge(l, r, d) ? "YES" : "NO");
    }
  }
  return 0;
}
