#include <iostream>
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
const int maxn = 1e6 + 10;
int n, m, k;
ull p[maxn];
ull b[maxn], b1[maxn];
ull base = 17, mod = 1e9 + 7;
struct segment_tree
{
int l;
int r;
ull w;
ull lazy;
} t[maxn * 4 + 10];
void update(int x)
{
t[x].w = t[x << 1].w * b[t[x << 1 | 1].r - t[x << 1 | 1].l + 1] + t[x << 1 | 1].w;
}
void build(int l, int r, int k)
{
t[k].l = l, t[k].r = r, t[k].lazy = -1;
if (l == r)
{
t[k].w = p[l];
return;
}
int mid = (l + r) >> 1;
build(l, mid, k << 1);
build(mid + 1, r, k << 1 | 1);
update(k);
}
void down(int k)
{
t[k << 1].lazy = t[k << 1 | 1].lazy = t[k].lazy;
t[k << 1].w = b1[t[k << 1].r - t[k << 1].l] * t[k].lazy;
t[k << 1 | 1].w = b1[t[k << 1 | 1].r - t[k << 1 | 1].l] * t[k].lazy;
t[k].lazy = -1;
}
ull interval_query(int k, int l, int r)
{
if (t[k].l > r || t[k].r < l)
return 0;
if (t[k].l == l && t[k].r == r)
return t[k].w;
if (t[k].lazy != -1)
down(k);
int mid = (t[k].l + t[k].r) >> 1;
if (mid >= r) return interval_query(k << 1, l, r);
else if (mid < l) return interval_query(k << 1 | 1, l, r);
else return interval_query(k << 1, l, mid) * b[r - mid] + interval_query(k << 1 | 1, mid + 1, r);
}
void interval_changing(int k, int l, int r, ull w)
{
if (t[k].l > r || t[k].r < l)
return;
if (t[k].l == l && t[k].r == r)
{
t[k].lazy = w;
t[k].w = b1[t[k].r - t[k].l] * w;
return;
}
if (t[k].lazy != -1)
down(k);
int mid = (t[k].l + t[k].r) >> 1;
if (mid >= r) interval_changing(k << 1, l, r, w);
else if (mid < l) interval_changing(k << 1 | 1, l, r, w);
else interval_changing(k << 1, l, mid, w), interval_changing(k << 1 | 1, mid + 1, r, w);
update(k);
}
int main() {
cin >> n >> m >> k;
b[0] = b1[0] = 1;
for (int i = 1; i < maxn; i++)
b[i] = b[i - 1] * base,
b1[i] = (b1[i - 1] * base + 1);
for (int i = 1; i <= n; i++)
{
char ch;
cin >> ch;
p[i] = ull(ch - '0') + 1;
}
build(1, n, 1);
m += k;
while (m--)
{
int opt, l, r;
ull d;
cin >> opt;
if (opt == 2)
{
cin >> l >> r >> d;
interval_query(1, l, r - d) == interval_query(1, l + d, r) ? cout << "YES" << endl : cout << "NO" << endl;
}
else
{
cin >> l >> r >> d;
interval_changing(1, l, r, d + 1);
}
}
return 0;
}
线段树+哈希,不知道炸哪了。