#include <bits/stdc++.h>
using namespace std;
pair<long long, long long> tree[400000], pwr[100005], inv;
int lazy[400000];
string s;
long long int power(long long int a, long long int b, long long m) {
  long long x = 1, y = a;
  while (b > 0) {
    if (b % 2 == 1) {
      x = (x * y);
      if (x > m) x %= m;
    }
    y = (y * y);
    if (y > m) y %= m;
    b /= 2;
  }
  return x;
}
void build_tree(int node, int a, int b) {
  if (a > b) return;
  if (a == b) {
    tree[node] = {s[a - 1] - '0' + 1, s[a - 1] - '0' + 1};
    return;
  }
  build_tree(node * 2, a, (a + b) / 2);
  build_tree(node * 2 + 1, 1 + (a + b) / 2, b);
  int rsz = b - (a + b) / 2;
  tree[node] = {
      (tree[node * 2].first * pwr[rsz].first + tree[node * 2 + 1].first) %
          1000000007,
      (tree[node * 2].second * pwr[rsz].second + tree[node * 2 + 1].second) %
          (1000000007 + 2)};
}
void update_tree(int node, int a, int b, int i, int j, int value) {
  if (lazy[node]) {
    tree[node].first =
        ((lazy[node] * ((pwr[b - a + 1].first - 1 + 1000000007) % 1000000007)) %
         1000000007 * inv.first) %
        1000000007;
    tree[node].second =
        ((lazy[node] *
          ((pwr[b - a + 1].second - 1 + 1000000007 + 2) % (1000000007 + 2))) %
         (1000000007 + 2) * inv.second) %
        (1000000007 + 2);
    if (a != b) {
      lazy[node * 2] = lazy[node];
      lazy[node * 2 + 1] = lazy[node];
    }
    lazy[node] = 0;
  }
  if (a > b || a > j || b < i) return;
  if (a >= i && b <= j) {
    tree[node].first =
        ((value * ((pwr[b - a + 1].first - 1 + 1000000007) % 1000000007)) %
         1000000007 * inv.first) %
        1000000007;
    tree[node].second =
        ((value *
          ((pwr[b - a + 1].second - 1 + 1000000007 + 2) % (1000000007 + 2))) %
         (1000000007 + 2) * inv.second) %
        (1000000007 + 2);
    if (a != b) {
      lazy[node * 2] = value;
      lazy[node * 2 + 1] = value;
    }
    return;
  }
  update_tree(node * 2, a, (a + b) / 2, i, j, value);
  update_tree(1 + node * 2, 1 + (a + b) / 2, b, i, j, value);
  int rsz = b - (a + b) / 2;
  tree[node] = {
      (tree[node * 2].first * pwr[rsz].first + tree[node * 2 + 1].first) %
          1000000007,
      (tree[node * 2].second * pwr[rsz].second + tree[node * 2 + 1].second) %
          (1000000007 + 2)};
}
pair<pair<long long, long long>, int> query_tree(int node, int a, int b, int i,
                                                 int j) {
  if (a > b || a > j || b < i) return {{0, 0}, 0};
  if (lazy[node]) {
    tree[node].first =
        ((lazy[node] * ((pwr[b - a + 1].first - 1 + 1000000007) % 1000000007)) %
         1000000007 * inv.first) %
        1000000007;
    tree[node].second =
        ((lazy[node] *
          ((pwr[b - a + 1].second - 1 + 1000000007 + 2) % (1000000007 + 2))) %
         (1000000007 + 2) * inv.second) %
        (1000000007 + 2);
    if (a != b) {
      lazy[node * 2] = lazy[node];
      lazy[node * 2 + 1] = lazy[node];
    }
    lazy[node] = 0;
  }
  if (a >= i && b <= j) return {tree[node], b - a + 1};
  pair<pair<long long, long long>, int> q1, q2, res;
  q1 = query_tree(node * 2, a, (a + b) / 2, i, j);
  q2 = query_tree(1 + node * 2, 1 + (a + b) / 2, b, i, j);
  res.second = q1.second + q2.second;
  res.first = {
      (q1.first.first * pwr[q2.second].first + q2.first.first) % 1000000007,
      (q1.first.second * pwr[q2.second].second + q2.first.second) %
          (1000000007 + 2)};
  return res;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int i, n, m, k, q, t, l, r, d;
  pair<long long, long long> q1, q2, q3, q4;
  inv = {power(11 - 1, 1000000007 - 2, 1000000007),
         power(11 - 1, 1000000007, 1000000007 + 2)};
  for (i = 1, pwr[0] = {1, 1}; i <= 100000; i++) {
    pwr[i].first = (pwr[i - 1].first * 11) % 1000000007;
    pwr[i].second = (pwr[i - 1].second * 11) % (1000000007 + 2);
  }
  cin >> n >> m >> k >> s;
  q = m + k;
  build_tree(1, 1, n);
  while (q--) {
    cin >> t >> l >> r >> d;
    if (t == 1)
      update_tree(1, 1, n, l, r, d + 1);
    else {
      q1 = query_tree(1, 1, n, l, l + d - 1).first;
      q2 = query_tree(1, 1, n, l, l + ((r - l + 1) / d) * d - 1).first;
      q1.first =
          (q1.first *
           ((pwr[((r - l + 1) / d) * d].first - 1 + 1000000007) % 1000000007)) %
          1000000007;
      q1.second = (q1.second *
                   ((pwr[((r - l + 1) / d) * d].second - 1 + 1000000007 + 2) %
                    (1000000007 + 2))) %
                  (1000000007 + 2);
      q2.first = (q2.first * ((pwr[d].first - 1 + 1000000007) % 1000000007)) %
                 1000000007;
      q2.second = (q2.second *
                   ((pwr[d].second - 1 + 1000000007 + 2) % (1000000007 + 2))) %
                  (1000000007 + 2);
      q3 = query_tree(1, 1, n, l, l + (r - l + 1) % d - 1).first;
      q4 = query_tree(1, 1, n, r - (r - l + 1) % d + 1, r).first;
      if (q1 == q2 && q3 == q4)
        cout << "YES" << '\n';
      else
        cout << "NO" << '\n';
    }
  }
  return 0;
}
