#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <functional>
#include <queue>
#define pf(x) ((x)*(x))
#define D(x) (1/x)
#define LL long long
#define lid (id<<1)
#define rid (id<<1|1)
using namespace std;
const double PI=3.141592653589793;
const LL N = 3e5 + 10;
const LL P = 1e9 + 7;
const LL M = 1e9 + 9;
char ch[N];
struct Segtree{
    LL l,r;
    LL lazy;
    LL hash;
}tr[N * 4];
LL f[N];
LL n,m,k;
LL g[N];
LL sg[N];

void Get_Hash(LL id)
{
    if(tr[rid].lazy > -1) tr[rid].hash = ( tr[rid].lazy * sg[ tr[rid].r - tr[rid].l + 1 ] ) % M;
    if(tr[lid].lazy > -1) tr[lid].hash = ( tr[lid].lazy * sg[ tr[lid].r - tr[lid].l + 1 ] ) % M;
    tr[id].hash = ( tr[lid].hash * g[ tr[rid].r - tr[rid].l + 2LL] + tr[rid].hash ) % M;
}

void print(LL id,LL l,LL r)
{
    printf("ID=%I64d L=%I64d R=%I64d lazy=%I64d hash=%I64d\n",id,l,r,tr[id].lazy,tr[id].hash);
    if(l==r) return;
    print(lid,tr[lid].l,tr[lid].r);
    print(rid,tr[rid].l,tr[rid].r);
}

void Initializer_Segtree(LL id,LL l,LL r)
{
    tr[id].lazy = -1;
    tr[id].l = l;
    tr[id].r = r;
    if(l == r)
    {
        tr[id].hash = ch[l - 1] - '0' + 1;
        return;
    }
    LL mid = (l + r) >> 1;
    Initializer_Segtree(lid,l,mid);
    Initializer_Segtree(rid,mid+1,r);
    Get_Hash(id);
}

void Change_Hash(LL id,LL l,LL r,LL num )
{
    if( tr[id].l == l && tr[id].r == r )
    {
        tr[id].lazy = num;
        tr[id].hash = (num * sg[r - l + 1LL]) % M;
        return;
    }

    if(tr[id].lazy > -1)
    {
        Change_Hash(lid,tr[lid].l,tr[lid].r,tr[id].lazy);
        Change_Hash(rid,tr[rid].l,tr[rid].r,tr[id].lazy);
        tr[id].lazy = -1;
    }

    if( tr[lid].r >= l ) Change_Hash( lid , l , min(r,tr[lid].r) , num );
    if( tr[rid].l <= r ) Change_Hash( rid , max(l,tr[rid].l) , r,num );
    Get_Hash(id);
}

LL Find_Hash(LL id,LL l,LL r)
{
    if(l>r) return 0;
    if( tr[id].lazy > -1 )
    {
        tr[lid].lazy = tr[id].lazy;
        tr[rid].lazy = tr[id].lazy;
        tr[id].hash = (tr[id].lazy * sg[ tr[id].r - tr[id].l + 1LL]) % M;
        tr[id].lazy = -1;
    }
    if( tr[id].l == l &&  tr[id].r == r)
      return tr[id].hash;

    LL s1,s2;
    s1 = s2 = 0;
    if( tr[lid].r >= l ) s1 = Find_Hash( lid , l , min(r,tr[lid].r) );
    if( tr[rid].l <= r ) s2 = Find_Hash( rid , max(l,tr[rid].l) , r );
    return s2 == 0 ? s1 : ( s1 * g[ r - tr[rid].l + 2LL ] + s2 ) % M;
}

void init()
{
    scanf("%I64d%I64d%I64d",&n,&m,&k);
    scanf("%s",ch);
    g[1] = sg[1] = 1LL;
    for(LL i = 2;i <= n + 5; i++ )
    {
        g[i] = ( g[i - 1] * P) % M;
        sg[i] = (g[i] + sg[i-1] ) % M;
    }

    Initializer_Segtree(1,1,n);
}

void work()
{
    LL sign,l,r,l0,num;
    for(LL i = 1;i <= m + k; i++)
    {
        scanf("%I64d",&sign);
        if(sign == 1)
        {
            scanf("%I64d %I64d %I64d",&l,&r,&num);
            Change_Hash(1,l,r,num + 1LL);
        }
        else
        {
            scanf("%I64d %I64d %I64d",&l,&r,&l0);
            if( Find_Hash(1,l,r-l0) == Find_Hash(1,l+l0,r)) printf("YES\n");
            else printf("NO\n");
        }
    }
}

int main()
{
    init();
    work();

    return 0;
}


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <functional>
#include <queue>
#define pf(x) ((x)*(x))
#define D(x) (1/x)
#define LL long long
#define lid (id<<1)
#define rid (id<<1|1)
using namespace std;
const double PI=3.141592653589793;
const LL N = 3e5 + 10;
const LL P = 1e9 + 7;
const LL M = 1e9 + 9;
char ch[N];
struct Segtree{
    LL l,r;
    LL lazy;
    LL hash;
}tr[N * 4];
LL f[N];
LL n,m,k;
LL g[N];
LL sg[N];

void Get_Hash(LL id)
{
    if(tr[rid].lazy > -1) tr[rid].hash = ( tr[rid].lazy * sg[ tr[rid].r - tr[rid].l + 1 ] ) % M;
    if(tr[lid].lazy > -1) tr[lid].hash = ( tr[lid].lazy * sg[ tr[lid].r - tr[lid].l + 1 ] ) % M;
    tr[id].hash = ( tr[lid].hash * g[ tr[rid].r - tr[rid].l + 2LL] + tr[rid].hash ) % M;
}

void print(LL id,LL l,LL r)
{
    printf("ID=%I64d L=%I64d R=%I64d lazy=%I64d hash=%I64d\n",id,l,r,tr[id].lazy,tr[id].hash);
    if(l==r) return;
    print(lid,tr[lid].l,tr[lid].r);
    print(rid,tr[rid].l,tr[rid].r);
}

void Initializer_Segtree(LL id,LL l,LL r)
{
    tr[id].lazy = -1;
    tr[id].l = l;
    tr[id].r = r;
    if(l == r)
    {
        tr[id].hash = ch[l - 1] - '0' + 1LL;
        return;
    }
    LL mid = (l + r) >> 1;
    Initializer_Segtree(lid,l,mid);
    Initializer_Segtree(rid,mid+1,r);
    Get_Hash(id);
}

void Change_Hash(LL id,LL l,LL r,LL num )
{
    if( tr[id].l == l && tr[id].r == r )
    {
        tr[id].lazy = num;
        tr[id].hash = (num * sg[r - l + 1LL]) % M;
        return;
    }

    if(tr[id].lazy > -1)
    {
        Change_Hash(lid,tr[lid].l,tr[lid].r,tr[id].lazy);
        Change_Hash(rid,tr[rid].l,tr[rid].r,tr[id].lazy);
        tr[id].lazy = -1;
    }

    if( tr[lid].r >= l ) Change_Hash( lid , l , min(r,tr[lid].r) , num );
    if( tr[rid].l <= r ) Change_Hash( rid , max(l,tr[rid].l) , r,num );
    Get_Hash(id);
}

LL Find_Hash(LL id,LL l,LL r)
{
    if(l>r) return 0;
    if( tr[id].lazy > -1 )
    {
        tr[lid].lazy = tr[id].lazy;
        tr[rid].lazy = tr[id].lazy;
        tr[id].hash = (tr[id].lazy * sg[ tr[id].r - tr[id].l + 1LL]) % M;
        tr[id].lazy = -1;
    }
    if( tr[id].l == l &&  tr[id].r == r)
      return tr[id].hash;

    LL s1,s2;
    s1 = s2 = -1;
    if( tr[lid].r >= l ) s1 = Find_Hash( lid , l , min(r,tr[lid].r) );
    if( tr[rid].l <= r ) s2 = Find_Hash( rid , max(l,tr[rid].l) , r );
    return s2 == -1 ? s1 : ( s1 * g[ r - tr[rid].l + 2LL ] + s2 ) % M;
}

void init()
{
    scanf("%I64d%I64d%I64d",&n,&m,&k);
    scanf("%s",ch);
    g[1] = sg[1] = 1LL;
    for(LL i = 2;i <= n + 5; i++ )
    {
        g[i] = ( g[i - 1] * P) % M;
        sg[i] = (g[i] + sg[i-1] ) % M;
    }

    Initializer_Segtree(1,1,n);
}

void work()
{
    LL sign,l,r,l0,num;
    for(LL i = 1;i <= m + k; i++)
    {
        scanf("%I64d",&sign);
        if(sign == 1)
        {
            scanf("%I64d %I64d %I64d",&l,&r,&num);
            Change_Hash(1,l,r,num + 1LL);
        }
        else
        {
            scanf("%I64d %I64d %I64d",&l,&r,&l0);
            if( Find_Hash(1,l,r-l0) == Find_Hash(1,l+l0,r)) printf("YES\n");
            else printf("NO\n");
        }
    }
}

int main()
{
    init();
    work();

    return 0;
}


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <functional>
#include <queue>
#define pf(x) ((x)*(x))
#define D(x) (1/x)
#define LL long long
#define lid (id<<1)
#define rid (id<<1|1)
using namespace std;
const double PI=3.141592653589793;
const LL N = 3e5 + 10;
const LL P = 233333333;
const LL M = 1e9 + 9;
char ch[N];
struct Segtree{
    LL l,r;
    LL lazy;
    LL hash;
}tr[N * 4];
LL f[N];
LL n,m,k;
LL g[N];
LL sg[N];

void Get_Hash(LL id)
{
    if(tr[rid].lazy > -1) tr[rid].hash = ( tr[rid].lazy * sg[ tr[rid].r - tr[rid].l + 1 ] ) % M;
    if(tr[lid].lazy > -1) tr[lid].hash = ( tr[lid].lazy * sg[ tr[lid].r - tr[lid].l + 1 ] ) % M;
    tr[id].hash = ( tr[lid].hash * g[ tr[rid].r - tr[rid].l + 2LL] + tr[rid].hash ) % M;
}

void print(LL id,LL l,LL r)
{
    printf("ID=%I64d L=%I64d R=%I64d lazy=%I64d hash=%I64d\n",id,l,r,tr[id].lazy,tr[id].hash);
    if(l==r) return;
    print(lid,tr[lid].l,tr[lid].r);
    print(rid,tr[rid].l,tr[rid].r);
}

void Initializer_Segtree(LL id,LL l,LL r)
{
    tr[id].lazy = -1;
    tr[id].l = l;
    tr[id].r = r;
    if(l == r)
    {
        tr[id].hash = ch[l - 1] - '0' + 1LL;
        return;
    }
    LL mid = (l + r) >> 1;
    Initializer_Segtree(lid,l,mid);
    Initializer_Segtree(rid,mid+1,r);
    Get_Hash(id);
}

void Change_Hash(LL id,LL l,LL r,LL num )
{
    if( tr[id].l == l && tr[id].r == r )
    {
        tr[id].lazy = num;
        tr[id].hash = (num * sg[r - l + 1LL]) % M;
        return;
    }

    if(tr[id].lazy > -1)
    {
        Change_Hash(lid,tr[lid].l,tr[lid].r,tr[id].lazy);
        Change_Hash(rid,tr[rid].l,tr[rid].r,tr[id].lazy);
        tr[id].lazy = -1;
    }

    if( tr[lid].r >= l ) Change_Hash( lid , l , min(r,tr[lid].r) , num );
    if( tr[rid].l <= r ) Change_Hash( rid , max(l,tr[rid].l) , r,num );
    Get_Hash(id);
}

LL Find_Hash(LL id,LL l,LL r)
{
    if(l>r) return 0;
    if( tr[id].lazy > -1 )
    {
        tr[lid].lazy = tr[id].lazy;
        tr[rid].lazy = tr[id].lazy;
        tr[id].hash = (tr[id].lazy * sg[ tr[id].r - tr[id].l + 1LL]) % M;
        tr[id].lazy = -1;
    }
    if( tr[id].l == l &&  tr[id].r == r)
      return tr[id].hash;

    LL s1,s2;
    s1 = 0;
    s2 = -1;
    if( tr[lid].r >= l ) s1 = Find_Hash( lid , l , min(r,tr[lid].r) );
    if( tr[rid].l <= r ) s2 = Find_Hash( rid , max(l,tr[rid].l) , r );
    return s2 == -1 ? s1 : ( s1 * g[ r - tr[rid].l + 2LL ] + s2 ) % M;
}

void init()
{
    scanf("%I64d%I64d%I64d",&n,&m,&k);
    scanf("%s",ch);
    g[1] = sg[1] = 1LL;
    for(LL i = 2;i <= n + 5; i++ )
    {
        g[i] = ( g[i - 1] * P) % M;
        sg[i] = (g[i] + sg[i-1] ) % M;
    }

    Initializer_Segtree(1,1,n);
}

void work()
{
    LL sign,l,r,l0,num;
    for(LL i = 1;i <= m + k; i++)
    {
        scanf("%I64d",&sign);
        if(sign == 1)
        {
            scanf("%I64d %I64d %I64d",&l,&r,&num);
            Change_Hash(1,l,r,num + 1LL);
        }
        else
        {
            scanf("%I64d %I64d %I64d",&l,&r,&l0);
            if( Find_Hash(1,l,r-l0) == Find_Hash(1,l+l0,r)) printf("YES\n");
            else printf("NO\n");
        }
    }
}

int main()
{
    init();
    work();

    return 0;
}


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <functional>
#include <queue>
#define pf(x) ((x)*(x))
#define D(x) (1/x)
#define LL long long
#define lid (id<<1)
#define rid (id<<1|1)
using namespace std;
const double PI=3.141592653589793;
const LL N = 3e5 + 10;
const LL P = 1e9 + 7;
const LL M = 1e9 + 9;
char ch[N];
struct Segtree{
    LL l,r;
    LL lazy;
    LL hash;
}tr[N * 4];
LL f[N];
LL n,m,k;
LL g[N];
LL sg[N];

void Get_Hash(LL id)
{
 /*   if(tr[id].lazy > 0)
    {
        tr[id].hash = ( ( sg[ tr[id].r - tr[id].l + 1] ) * tr[id].lazy ) % M;
        return;
    }

    if(tr[id].l == tr[id].r ) return;*/

    tr[id].hash = ( tr[lid].hash * g[ tr[rid].r - tr[rid].l + 2LL] + tr[rid].hash ) % M;
}

void print(LL id,LL l,LL r)
{
    printf("ID=%I64d L=%I64d R=%I64d lazy=%I64d hash=%I64d\n",id,l,r,tr[id].lazy,tr[id].hash);
    if(l==r) return;
    print(lid,tr[lid].l,tr[lid].r);
    print(rid,tr[rid].l,tr[rid].r);
}

void Initializer_Segtree(LL id,LL l,LL r)
{
    tr[id].lazy = 0;
    tr[id].l = l;
    tr[id].r = r;
    if(l == r)
    {
        tr[id].hash = ch[l - 1] - '0' + 1LL;
        return;
    }
    LL mid = (l + r) >> 1;
    Initializer_Segtree(lid,l,mid);
    Initializer_Segtree(rid,mid+1,r);
    Get_Hash(id);
}

void Change_Hash(LL id,LL l,LL r,LL num )
{
    if( tr[id].l == l && tr[id].r == r )
    {
        tr[id].lazy = num;
        tr[id].hash = (num * sg[r - l + 1LL]) % M;
        return;
    }

    if(tr[id].lazy > 0)
    {
        Change_Hash(lid,tr[lid].l,tr[lid].r,tr[id].lazy);
        Change_Hash(lid,tr[rid].l,tr[rid].r,tr[id].lazy);
        tr[id].lazy = 0;
    }

    if( tr[lid].r >= l ) Change_Hash( lid , l , min(r,tr[lid].r) , num );
    if( tr[rid].l <= r ) Change_Hash( rid , max(l,tr[rid].l) , r,num );
    Get_Hash(id);
}

LL Find_Hash(LL id,LL l,LL r)
{
    if(l>r) return 0;
  //  cout<<id<<" "<<l<<" "<<r<<endl;
    if( tr[id].lazy > 0 )
    {
        tr[lid].lazy = tr[id].lazy;
        tr[rid].lazy = tr[id].lazy;
        tr[id].hash = (tr[id].lazy * sg[ tr[id].r - tr[id].l + 1LL]) % M;
        tr[id].lazy = 0;
    }
    if( tr[id].l == l &&  tr[id].r == r)
      return tr[id].hash;

    LL s1,s2;
    s1 = s2 = 0;
    if( tr[lid].r >= l ) s1 = Find_Hash( lid , l , min(r,tr[lid].r) );
    if( tr[rid].l <= r ) s2 = Find_Hash( rid , max(l,tr[rid].l) , r );
    return s2 == 0 ? s1 : ( s1 * g[ r - tr[rid].l + 2LL ] + s2 ) % M;
}

void init()
{
    scanf("%I64d%I64d%I64d",&n,&m,&k);
    scanf("%s",ch);
    g[1] = sg[1] = 1LL;
    for(LL i = 2;i <= n + 5; i++ )
    {
        g[i] = ( g[i - 1] * P) % M;
        sg[i] = (g[i] + sg[i-1] ) % M;
       // cout<<g[i] << " "<<sg[i]<<endl;
    }

    Initializer_Segtree(1,1,n);
}

void work()
{
    LL sign,l,r,l0,num;

    for(LL i = 1;i <= m + k; i++)
    {
        scanf("%I64d",&sign);
        if(sign == 1)
        {
            scanf("%I64d %I64d %I64d",&l,&r,&num);
            Change_Hash(1,l,r,num+1LL);
        }
        else
        {

            scanf("%I64d %I64d %I64d",&l,&r,&l0);
            if( Find_Hash(1,l,r-l0) == Find_Hash(1,l+l0,r)) printf("YES\n");
            else printf("NO\n");
        }
    }
}

int main()
{
    init();
    work();

    return 0;
}


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <functional>
#include <queue>
#define pf(x) ((x)*(x))
#define D(x) (1/x)
#define LL long long
#define lid (id<<1)
#define rid (id<<1|1)
using namespace std;
const double PI=3.141592653589793;
const LL N = 3e5 + 10;
const LL P = 1e9 + 7;
const LL M = 1e9 + 9;
char ch[N];
struct Segtree{
    LL l,r;
    LL lazy;
    LL hash;
}tr[N * 4];
LL f[N];
LL n,m,k;
LL g[N];
LL sg[N];

void Get_Hash(LL id)
{
 /*   if(tr[id].lazy > 0)
    {
        tr[id].hash = ( ( sg[ tr[id].r - tr[id].l + 1] ) * tr[id].lazy ) % M;
        return;
    }

    if(tr[id].l == tr[id].r ) return;*/

    tr[id].hash = ( tr[lid].hash * g[ tr[rid].r - tr[rid].l + 2LL] + tr[rid].hash ) % M;
}

void print(LL id,LL l,LL r)
{
    printf("ID=%I64d L=%I64d R=%I64d lazy=%I64d hash=%I64d\n",id,l,r,tr[id].lazy,tr[id].hash);
    if(l==r) return;
    print(lid,tr[lid].l,tr[lid].r);
    print(rid,tr[rid].l,tr[rid].r);
}

void Initializer_Segtree(LL id,LL l,LL r)
{
    tr[id].lazy = 0;
    tr[id].l = l;
    tr[id].r = r;
    if(l == r)
    {
        tr[id].hash = ch[l - 1] - '0' + 1LL;
        return;
    }
    LL mid = (l + r) >> 1;
    Initializer_Segtree(lid,l,mid);
    Initializer_Segtree(rid,mid+1,r);
    Get_Hash(id);
}

void Change_Hash(LL id,LL l,LL r,LL num )
{
    if( tr[id].l == l && tr[id].r == r )
    {
        tr[id].lazy = num;
        tr[id].hash = (num * sg[r - l + 1LL]) % M;
        return;
    }

    if(tr[id].lazy > 0)
    {
        Change_Hash(lid,tr[lid].l,tr[lid].r,tr[id].hash);
        Change_Hash(lid,tr[rid].l,tr[rid].r,tr[id].hash);
        tr[id].lazy = 0;
    }

    if( tr[lid].r >= l ) Change_Hash( lid , l , min(r,tr[lid].r) , num );
    if( tr[rid].l <= r ) Change_Hash( rid , max(l,tr[rid].l) , r,num );
    Get_Hash(id);
}

LL Find_Hash(LL id,LL l,LL r)
{
    if(l>r) return 0;
  //  cout<<id<<" "<<l<<" "<<r<<endl;
    if( tr[id].lazy > 0 )
    {
        tr[lid].lazy = tr[id].lazy;
        tr[rid].lazy = tr[id].lazy;
        tr[id].hash = (tr[id].lazy * sg[ tr[id].r - tr[id].l + 1LL]) % M;
        tr[id].lazy = 0;
    }
    if( tr[id].l == l &&  tr[id].r == r)
      return tr[id].hash;

    LL s1,s2;
    s1 = s2 = 0;
    if( tr[lid].r >= l ) s1 = Find_Hash( lid , l , min(r,tr[lid].r) );
    if( tr[rid].l <= r ) s2 = Find_Hash( rid , max(l,tr[rid].l) , r );
    return s2 == 0 ? s1 : ( s1 * g[ r - tr[rid].l + 2LL ] + s2 ) % M;
}

void init()
{
    scanf("%I64d%I64d%I64d",&n,&m,&k);
    scanf("%s",ch);
    g[1] = sg[1] = 1LL;
    for(LL i = 2;i <= n + 5; i++ )
    {
        g[i] = ( g[i - 1] * P) % M;
        sg[i] = (g[i] + sg[i-1] ) % M;
       // cout<<g[i] << " "<<sg[i]<<endl;
    }

    Initializer_Segtree(1,1,n);
}

void work()
{
    LL sign,l,r,l0,num;

    for(LL i = 1;i <= m + k; i++)
    {
        scanf("%I64d",&sign);
        if(sign == 1)
        {
            scanf("%I64d %I64d %I64d",&l,&r,&num);
            Change_Hash(1,l,r,num+1LL);
        }
        else
        {

            scanf("%I64d %I64d %I64d",&l,&r,&l0);
            if( Find_Hash(1,l,r-l0) == Find_Hash(1,l+l0,r)) printf("YES\n");
            else printf("NO\n");
        }
    }
}

int main()
{
    init();
    work();

    return 0;
}


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <functional>
#include <queue>
#define pf(x) ((x)*(x))
#define D(x) (1/x)
#define LL long long
#define lid (id<<1)
#define rid (id<<1|1)
using namespace std;
const double PI=3.141592653589793;
const LL N = 3e5 + 10;
const LL P = 1e9 + 7;
const LL M = 1e9 + 9;
char ch[N];
struct Segtree{
    LL l,r;
    LL lazy;
    LL hash;
}tr[N * 4];
LL f[N];
LL n,m,k;
LL g[N];
LL sg[N];

void Get_Hash(LL id)
{
    if(tr[rid].lazy > -1) tr[rid].hash = ( tr[rid].lazy * sg[ tr[rid].r - tr[rid].l + 1 ] ) % M;
    if(tr[lid].lazy > -1) tr[lid].hash = ( tr[lid].lazy * sg[ tr[lid].r - tr[lid].l + 1 ] ) % M;
    tr[id].hash = ( tr[lid].hash * g[ tr[rid].r - tr[rid].l + 2LL] + tr[rid].hash ) % M;
}

void print(LL id,LL l,LL r)
{
    printf("ID=%I64d L=%I64d R=%I64d lazy=%I64d hash=%I64d\n",id,l,r,tr[id].lazy,tr[id].hash);
    if(l==r) return;
    print(lid,tr[lid].l,tr[lid].r);
    print(rid,tr[rid].l,tr[rid].r);
}

void Initializer_Segtree(LL id,LL l,LL r)
{
    tr[id].lazy = -1;
    tr[id].l = l;
    tr[id].r = r;
    if(l == r)
    {
        tr[id].hash = ch[l - 1] - '0' + 1LL;
        return;
    }
    LL mid = (l + r) >> 1;
    Initializer_Segtree(lid,l,mid);
    Initializer_Segtree(rid,mid+1,r);
    Get_Hash(id);
}

void Change_Hash(LL id,LL l,LL r,LL num )
{
    if( tr[id].l == l && tr[id].r == r )
    {
        tr[id].lazy = num;
        tr[id].hash = (num * sg[r - l + 1LL]) % M;
        return;
    }

    if(tr[id].lazy > -1)
    {
        Change_Hash(lid,tr[lid].l,tr[lid].r,tr[id].lazy);
        Change_Hash(rid,tr[rid].l,tr[rid].r,tr[id].lazy);
        tr[id].lazy = -1;
    }

    if( tr[lid].r >= l ) Change_Hash( lid , l , min(r,tr[lid].r) , num );
    if( tr[rid].l <= r ) Change_Hash( rid , max(l,tr[rid].l) , r,num );
    Get_Hash(id);
}

LL Find_Hash(LL id,LL l,LL r)
{
    if(l>r) return 0;
    if( tr[id].lazy > -1 )
    {
        tr[lid].lazy = tr[id].lazy;
        tr[rid].lazy = tr[id].lazy;
        tr[id].hash = (tr[id].lazy * sg[ tr[id].r - tr[id].l + 1LL]) % M;
        tr[id].lazy = -1;
    }
    if( tr[id].l == l &&  tr[id].r == r)
      return tr[id].hash;

    LL s1,s2;
    s1 = 0;
    s2 = -1;
    if( tr[lid].r >= l ) s1 = Find_Hash( lid , l , min(r,tr[lid].r) );
    if( tr[rid].l <= r ) s2 = Find_Hash( rid , max(l,tr[rid].l) , r );
    return s2 == -1 ? s1 : ( s1 * g[ r - tr[rid].l + 2LL ] + s2 ) % M;
}

void init()
{
    scanf("%I64d%I64d%I64d",&n,&m,&k);
    scanf("%s",ch);
    g[1] = sg[1] = 1LL;
    for(LL i = 2;i <= n + 5; i++ )
    {
        g[i] = ( g[i - 1] * P) % M;
        sg[i] = (g[i] + sg[i-1] ) % M;
    }

    Initializer_Segtree(1,1,n);
}

void work()
{
    LL sign,l,r,l0,num;
    for(LL i = 1;i <= m + k; i++)
    {
        scanf("%I64d",&sign);
        if(sign == 1)
        {
            scanf("%I64d %I64d %I64d",&l,&r,&num);
            Change_Hash(1,l,r,num + 1LL);
        }
        else
        {
            scanf("%I64d %I64d %I64d",&l,&r,&l0);
            if( Find_Hash(1,l,r-l0) == Find_Hash(1,l+l0,r)) printf("YES\n");
            else printf("NO\n");
        }
    }
}

int main()
{
    init();
    work();

    return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 1000000009
#define p 257
#define f1 first
#define s1 second
using namespace std;
typedef pair <int,int> pii;
int n,m,k,i,j,tip,x,y,per,v[3*nmax],pp1[nmax],ss1[nmax],pp2[nmax],ss2[nmax];
char s[nmax];
pii sol,arb[3*nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==0) return; else
    {
        arb[nod].f1=(1LL*ss1[dr-st]*v[nod])%mod1;
        arb[nod].s1=(1LL*ss2[dr-st]*v[nod])%mod2;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=0;
    }
}
void build(int nod,int st,int dr)
{
    if (st==dr) arb[nod].f1=s[st]-48,arb[nod].s1=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(1LL*per*ss1[dr-st])%mod1;
        arb[nod].s1=(1LL*per*ss2[dr-st])%mod2;
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp1[dr-st+1]+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp2[dr-st+1]+arb[nod].s1)%mod2;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int st,int dr)
{
    sol={0,0}; query(1,1,n,st,dr);
    return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1);
pp1[0]=1; ss1[0]=1; pp2[0]=1; ss2[0]=1;
for (i=1;i<=n;i++) {
    pp1[i]=(1LL*pp1[i-1]*p)%mod1,ss1[i]=(1LL*ss1[i-1]*p+pp1[i])%mod1;
    pp2[i]=(1LL*pp2[i-1]*p)%mod2,ss2[i]=(1LL*ss2[i-1]*p+pp2[i])%mod2;
}
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(x+per,y)==squery(x,y-per)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 1000000009
#define p 191
#define f1 first
#define s1 second
using namespace std;
typedef pair <long long,long long> pii;
int n,m,k,i,j,tip,x,y,per,v[3*nmax],pp1[nmax],ss1[nmax],pp2[nmax],ss2[nmax];
char s[nmax];
pii sol,arb[3*nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==0) return; else
    {
        arb[nod].f1=(1LL*ss1[dr-st]*v[nod])%mod1;
        arb[nod].s1=(1LL*ss2[dr-st]*v[nod])%mod2;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=0;
    }
}
void build(int nod,int st,int dr)
{
    if (st==dr) arb[nod].f1=s[st]-48,arb[nod].s1=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(1LL*per*ss1[dr-st])%mod1;
        arb[nod].s1=(1LL*per*ss2[dr-st])%mod2;
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp1[dr-st+1]+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp2[dr-st+1]+arb[nod].s1)%mod2;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int st,int dr)
{
    sol={0,0}; query(1,1,n,st,dr);
    return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1);
pp1[0]=1; ss1[0]=1; pp2[0]=1; ss2[0]=1;
for (i=1;i<=n;i++) {
    pp1[i]=(1LL*pp1[i-1]*p)%mod1,ss1[i]=(1LL*ss1[i-1]*p+1)%mod1;
    pp2[i]=(1LL*pp2[i-1]*p)%mod2,ss2[i]=(1LL*ss2[i-1]*p+1)%mod2;
}
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(x+per,y)==squery(x,y-per)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 1000000009
#define p 257
#define f1 first
#define s1 second
using namespace std;
typedef pair <int,int> pii;
int n,m,k,i,j,tip,x,y,per,v[3*nmax],pp1[nmax],ss1[nmax],pp2[nmax],ss2[nmax];
char s[nmax];
pii sol,arb[3*nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==0) return; else
    {
        arb[nod].f1=(1LL*ss1[dr-st]*v[nod])%mod1;
        arb[nod].s1=(1LL*ss2[dr-st]*v[nod])%mod2;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=0;
    }
}
void build(int nod,int st,int dr)
{
    if (st==dr) arb[nod].f1=s[st]-48,arb[nod].s1=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(1LL*per*ss1[dr-st])%mod1;
        arb[nod].s1=(1LL*per*ss2[dr-st])%mod2;
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp1[dr-st+1]+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp2[dr-st+1]+arb[nod].s1)%mod2;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int st,int dr)
{
    sol={0,0}; query(1,1,n,st,dr);
    return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1);
pp1[0]=1; ss1[0]=1; pp2[0]=1; ss2[0]=1;
for (i=1;i<=n;i++) {
    pp1[i]=(1LL*pp1[i-1]*p)%mod1,ss1[i]=(1LL*ss1[i-1]*p+1)%mod1;
    pp2[i]=(1LL*pp2[i-1]*p)%mod2,ss2[i]=(1LL*ss2[i-1]*p+1)%mod2;
}
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(x+per,y)==squery(x,y-per)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 1000000009
#define p 257
#define f1 first
#define s1 second
using namespace std;
typedef pair <int,int> pii;
int n,m,k,i,j,tip,x,y,per,v[3*nmax],pp1[nmax],ss1[nmax],pp2[nmax],ss2[nmax];
char s[nmax];
pii sol,arb[3*nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==0) return; else
    {
        arb[nod].f1=(1LL*ss1[dr-st]*v[nod])%mod1;
        arb[nod].s1=(1LL*ss2[dr-st]*v[nod])%mod2;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=0;
    }
}
void build(int nod,int st,int dr)
{
    if (st==dr) arb[nod].f1=s[st]-47,arb[nod].s1=s[st]-47; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(1LL*per*ss1[dr-st])%mod1;
        arb[nod].s1=(1LL*per*ss2[dr-st])%mod2;
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp1[dr-st+1]+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp2[dr-st+1]+arb[nod].s1)%mod2;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int st,int dr)
{
    sol={0,0}; query(1,1,n,st,dr);
    return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1);
pp1[0]=1; ss1[0]=1; pp2[0]=1; ss2[0]=1;
for (i=1;i<=n;i++) {
    pp1[i]=(1LL*pp1[i-1]*p)%mod1,ss1[i]=(1LL*ss1[i-1]*p+1)%mod1;
    pp2[i]=(1LL*pp2[i-1]*p)%mod2,ss2[i]=(1LL*ss2[i-1]*p+1)%mod2;
}
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(x+per,y)==squery(x,y-per)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 1000000009
#define p 257
#define f1 first
#define s1 second
using namespace std;
typedef pair <long long,long long> pii;
int n,m,k,i,j,tip,x,y,per,v[3*nmax],pp1[nmax],ss1[nmax],pp2[nmax],ss2[nmax];
char s[nmax];
pii sol,arb[3*nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==0) return; else
    {
        arb[nod].f1=(1LL*ss1[dr-st]*v[nod])%mod1;
        arb[nod].s1=(1LL*ss2[dr-st]*v[nod])%mod2;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=0;
    }
}
void build(int nod,int st,int dr)
{
    if (st==dr) arb[nod].f1=s[st]-48,arb[nod].s1=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(1LL*per*ss1[dr-st])%mod1;
        arb[nod].s1=(1LL*per*ss2[dr-st])%mod2;
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp1[dr-st+1]+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp2[dr-st+1]+arb[nod].s1)%mod2;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int st,int dr)
{
    sol={0,0}; query(1,1,n,st,dr);
    return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1);
pp1[0]=1; ss1[0]=1; pp2[0]=1; ss2[0]=1;
for (i=1;i<=n;i++) {
    pp1[i]=(1LL*pp1[i-1]*p)%mod1,ss1[i]=(1LL*ss1[i-1]*p+1)%mod1;
    pp2[i]=(1LL*pp2[i-1]*p)%mod2,ss2[i]=(1LL*ss2[i-1]*p+1)%mod2;
}
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(x+per,y)==squery(x,y-per)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 666013
#define p 257
#define f1 first
#define s1 second
using namespace std;
typedef pair <int,int> pii;
int n,m,k,i,j,tip,x,y,per,v[3*nmax],pp1[nmax],ss1[nmax],pp2[nmax],ss2[nmax];
char s[nmax];
pii sol,arb[3*nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==0) return; else
    {
        arb[nod].f1=(1LL*ss1[dr-st]*v[nod])%mod1;
        arb[nod].s1=(1LL*ss2[dr-st]*v[nod])%mod2;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=0;
    }
}
void build(int nod,int st,int dr)
{
    if (st==dr) arb[nod].f1=s[st]-48,arb[nod].s1=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(per*ss1[dr-st])%mod1;
        arb[nod].s1=(per*ss2[dr-st])%mod2;
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp1[dr-st]+1+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp2[dr-st]+1+arb[nod].s1)%mod2;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int st,int dr)
{
    sol={0,0}; query(1,1,n,st,dr); return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1);
pp1[0]=1; ss1[0]=1; pp2[0]=1; ss2[0]=1;
for (i=1;i<=n;i++) {
    pp1[i]=(1LL*pp1[i-1]*p)%mod1,ss1[i]=(1LL*ss1[i-1]*p+1)%mod1;
    pp2[i]=(1LL*pp2[i-1]*p)%mod2,ss2[i]=(1LL*ss2[i-1]*p+1)%mod2;
}
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(x,x+per-1)==squery(y-per+1,y)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 1000000009
#define p 257
#define f1 first
#define s1 second
using namespace std;
typedef pair <int,int> pii;
int n,m,k,i,j,tip,x,y,per,v[nmax]; char s[nmax];
pii arb[3*nmax],pp[nmax],ss[nmax],sol;
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==-1) return;
    arb[nod].f1=(1LL*v[nod]*ss[dr-st].f1)%mod1;
    arb[nod].s1=(1LL*v[nod]*ss[dr-st].s1)%mod2;
    if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
    v[nod]=-1;
}
void build(int nod,int st,int dr)
{
    v[nod]=-1;
    if (st==dr) arb[nod].f1=s[st]-48,arb[nod].s1=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp[dr-m].f1+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp[dr-m].s1+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(1LL*per*ss[dr-st].f1)%mod1;
        arb[nod].s1=(1LL*per*ss[dr-st].s1)%mod2;
        if (st!=dr) { v[nod*2]=per; v[nod*2+1]=per; }
    }
    else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m);
        if (y>m) update(nod*2+1,m+1,dr);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp[dr-m].f1+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp[dr-m].s1+arb[nod*2+1].s1)%mod2;
    }
}
inline int query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp[dr-st+1].f1+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp[dr-st+1].s1+arb[nod].s1)%mod2;
    } else {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
        if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int nod,int st,int dr,int x,int y)
{
    sol={0,0}; query(nod,st,dr,x,y); return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
pp[0]=ss[0]={1,1};
for (i=1;i<=n;i++) {
    pp[i].f1=(1LL*pp[i-1].f1*p)%mod1,ss[i].f1=(1LL*ss[i-1].f1*p+1)%mod1;
    pp[i].s1=(1LL*pp[i-1].s1*p)%mod2,ss[i].s1=(1LL*ss[i-1].s1*p+1)%mod2;
}
gets(s+1); build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(1,1,n,x+per,y)==squery(1,1,n,x,y-per)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 666013
#define p 10
#define f1 first
#define s1 second
using namespace std;
typedef pair <int,int> pii;
int n,m,k,i,j,tip,x,y,per,v[3*nmax],pp1[nmax],ss1[nmax],pp2[nmax],ss2[nmax];
char s[nmax];
pii sol,arb[3*nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==0) return; else
    {
        arb[nod].f1=(1LL*ss1[dr-st]*v[nod])%mod1;
        arb[nod].s1=(1LL*ss2[dr-st]*v[nod])%mod2;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=0;
    }
}
void build(int nod,int st,int dr)
{
    if (st==dr) arb[nod].f1=s[st]-48,arb[nod].s1=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(per*ss1[dr-st])%mod1;
        arb[nod].s1=(per*ss2[dr-st])%mod2;
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp1[dr-st+1]+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp2[dr-st+1]+arb[nod].s1)%mod2;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int st,int dr)
{
    sol={0,0}; query(1,1,n,st,dr);
    return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1);
pp1[0]=1; ss1[0]=1; pp2[0]=1; ss2[0]=1;
for (i=1;i<=n;i++) {
    pp1[i]=(1LL*pp1[i-1]*p)%mod1,ss1[i]=(1LL*ss1[i-1]*p+1)%mod1;
    pp2[i]=(1LL*pp2[i-1]*p)%mod2,ss2[i]=(1LL*ss2[i-1]*p+1)%mod2;
}
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(x+per,y)==squery(x,y-per)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 1000000009
#define p 257
#define f1 first
#define s1 second
using namespace std;
typedef pair <int,int> pii;
int n,m,k,i,j,tip,x,y,per,v[3*nmax],pp1[nmax],ss1[nmax],pp2[nmax],ss2[nmax];
char s[nmax];
pii sol,arb[3*nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==0) return; else
    {
        arb[nod].f1=(1LL*ss1[dr-st]*v[nod])%mod1;
        arb[nod].s1=(1LL*ss2[dr-st]*v[nod])%mod2;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=0;
    }
}
void build(int nod,int st,int dr)
{
    if (st==dr) arb[nod].f1=s[st]-48,arb[nod].s1=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(per*ss1[dr-st])%mod1;
        arb[nod].s1=(per*ss2[dr-st])%mod2;
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp1[dr-st+1]+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp2[dr-st+1]+arb[nod].s1)%mod2;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int st,int dr)
{
    sol={0,0}; query(1,1,n,st,dr);
    return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1);
pp1[0]=1; ss1[0]=1; pp2[0]=1; ss2[0]=1;
for (i=1;i<=n;i++) {
    pp1[i]=(1LL*pp1[i-1]*p)%mod1,ss1[i]=(1LL*ss1[i-1]*p+1)%mod1;
    pp2[i]=(1LL*pp2[i-1]*p)%mod2,ss2[i]=(1LL*ss2[i-1]*p+1)%mod2;
}
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(x+per,y)==squery(x,y-per)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#define nmax 100010
#define mod 1000000007
#define p 257
using namespace std;
int n,m,k,i,j,tip,x,y,per,arb[3*nmax],v[3*nmax],pp[nmax],ss[nmax],sol;
char s[nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==0) return; else
    {
        arb[nod]=(1LL*ss[dr-st]*v[nod])%mod;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=0;
    }
}
void build(int nod,int st,int dr)
{
    if (st==dr) arb[nod]=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod]=(arb[nod*2]*pp[dr-m]+arb[nod*2+1])%mod;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod]=per*ss[dr-st];
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod]=(arb[nod*2]*pp[dr-m]+arb[nod*2+1])%mod;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) { sol=(1LL*sol*pp[dr-st]+1+arb[nod])%mod; return; } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline int squery(int st,int dr)
{
    sol=0; query(1,1,n,st,dr); return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1); pp[0]=1; ss[0]=1;
for (i=1;i<=n;i++)
    pp[i]=(1LL*pp[i-1]*p)%mod,ss[i]=(1LL*ss[i-1]*p+1)%mod;
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (squery(x,y-per)==squery(y-per+1,y)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 1000000009
#define p 10
#define f1 first
#define s1 second
using namespace std;
typedef pair <int,int> pii;
int n,m,k,i,j,tip,x,y,per,v[3*nmax],pp1[nmax],ss1[nmax],pp2[nmax],ss2[nmax];
char s[nmax];
pii sol,arb[3*nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==0) return; else
    {
        arb[nod].f1=(1LL*ss1[dr-st]*v[nod])%mod1;
        arb[nod].s1=(1LL*ss2[dr-st]*v[nod])%mod2;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=0;
    }
}
void build(int nod,int st,int dr)
{
    if (st==dr) arb[nod].f1=s[st]-48,arb[nod].s1=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(per*ss1[dr-st])%mod1;
        arb[nod].s1=(per*ss2[dr-st])%mod2;
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp1[dr-st+1]+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp2[dr-st+1]+arb[nod].s1)%mod2;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int st,int dr)
{
    sol={0,0}; query(1,1,n,st,dr);
    return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1);
pp1[0]=1; ss1[0]=1; pp2[0]=1; ss2[0]=1;
for (i=1;i<=n;i++) {
    pp1[i]=(1LL*pp1[i-1]*p)%mod1,ss1[i]=(1LL*ss1[i-1]*p+1)%mod1;
    pp2[i]=(1LL*pp2[i-1]*p)%mod2,ss2[i]=(1LL*ss2[i-1]*p+1)%mod2;
}
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(x+per,y)==squery(x,y-per)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 1000000009
#define p 257
#define f1 first
#define s1 second
using namespace std;
typedef pair <int,int> pii;
int n,m,k,i,j,tip,x,y,per,v[3*nmax]; char s[nmax];
pii arb[3*nmax],pp[nmax],ss[nmax],sol;
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==-1) return;
    arb[nod].f1=(1LL*v[nod]*ss[dr-st].f1)%mod1;
    arb[nod].s1=(1LL*v[nod]*ss[dr-st].s1)%mod2;
    if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
    v[nod]=-1;
}
void build(int nod,int st,int dr)
{
    v[nod]=-1;
    if (st==dr) arb[nod].f1=s[st]-48,arb[nod].s1=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp[dr-m].f1+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp[dr-m].s1+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(1LL*per*ss[dr-st].f1)%mod1;
        arb[nod].s1=(1LL*per*ss[dr-st].s1)%mod2;
        if (st!=dr) { v[nod*2]=per; v[nod*2+1]=per; }
    }
    else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m);
        if (y>m) update(nod*2+1,m+1,dr);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp[dr-m].f1+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp[dr-m].s1+arb[nod*2+1].s1)%mod2;
    }
}
inline int query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp[dr-st+1].f1+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp[dr-st+1].s1+arb[nod].s1)%mod2;
    } else {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
        if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int nod,int st,int dr,int x,int y)
{
    sol={0,0}; query(nod,st,dr,x,y); return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
pp[0]=ss[0]={1,1};
for (i=1;i<=n;i++) {
    pp[i].f1=(1LL*pp[i-1].f1*p)%mod1,ss[i].f1=(1LL*ss[i-1].f1*p+1)%mod1;
    pp[i].s1=(1LL*pp[i-1].s1*p)%mod2,ss[i].s1=(1LL*ss[i-1].s1*p+1)%mod2;
}
gets(s+1); build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(1,1,n,x+per,y)==squery(1,1,n,x,y-per)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#define nmax 100010
#define mod 1000000007
#define p 257
using namespace std;
int n,m,k,i,j,tip,x,y,per,arb[3*nmax],v[3*nmax],pp[nmax],ss[nmax],sol;
char s[nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==0) return; else
    {
        arb[nod]=(1LL*ss[dr-st]*v[nod])%mod;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=0;
    }
}
void build(int nod,int st,int dr)
{
    if (st==dr) arb[nod]=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod]=(arb[nod*2]*pp[dr-m]+arb[nod*2+1])%mod;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod]=per*ss[dr-st];
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod]=(arb[nod*2]*pp[dr-m]+arb[nod*2+1])%mod;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) { sol=(1LL*sol*pp[dr-st]+1+arb[nod])%mod; return; } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline int squery(int st,int dr)
{
    sol=0; query(1,1,n,st,dr); return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1); pp[0]=1; ss[0]=1;
for (i=1;i<=n;i++)
    pp[i]=(1LL*pp[i-1]*p)%mod,ss[i]=(1LL*ss[i-1]*p+1)%mod;
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(x,y-per)==squery(y-per+1,y)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 1000000009
#define p 267
#define f1 first
#define s1 second
using namespace std;
typedef pair <int,int> pii;
int n,m,k,i,j,tip,x,y,per,v[3*nmax],pp1[nmax],ss1[nmax],pp2[nmax],ss2[nmax];
char s[nmax];
pii sol,arb[3*nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==-1) return; else
    {
        arb[nod].f1=(1LL*ss1[dr-st]*v[nod])%mod1;
        arb[nod].s1=(1LL*ss2[dr-st]*v[nod])%mod2;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=-1;
    }
}
void build(int nod,int st,int dr)
{
    v[nod]=-1;
    if (st==dr) arb[nod].f1=s[st]-48,arb[nod].s1=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(1LL*per*ss1[dr-st])%mod1;
        arb[nod].s1=(1LL*per*ss2[dr-st])%mod2;
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp1[dr-st+1]+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp2[dr-st+1]+arb[nod].s1)%mod2;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int st,int dr)
{
    sol={0,0}; query(1,1,n,st,dr);
    return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1);
pp1[0]=1; ss1[0]=1; pp2[0]=1; ss2[0]=1;
for (i=1;i<=n;i++) {
    pp1[i]=(1LL*pp1[i-1]*p)%mod1,ss1[i]=(1LL*ss1[i-1]*p+1)%mod1;
    pp2[i]=(1LL*pp2[i-1]*p)%mod2,ss2[i]=(1LL*ss2[i-1]*p+1)%mod2;
}
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(x+per,y)==squery(x,y-per)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


#include <stdio.h>
#include <utility>
#define nmax 100010
#define mod1 1000000007
#define mod2 1000000009
#define p 10
#define f1 first
#define s1 second
using namespace std;
typedef pair <int,int> pii;
int n,m,k,i,j,tip,x,y,per,v[3*nmax],pp1[nmax],ss1[nmax],pp2[nmax],ss2[nmax];
char s[nmax];
pii sol,arb[3*nmax];
inline void lazypropagation(int nod,int st,int dr)
{
    if (v[nod]==-1) return; else
    {
        arb[nod].f1=(1LL*ss1[dr-st]*v[nod])%mod1;
        arb[nod].s1=(1LL*ss2[dr-st]*v[nod])%mod2;
        if (st!=dr) { v[nod*2]=v[nod]; v[nod*2+1]=v[nod]; }
        v[nod]=-1;
    }
}
void build(int nod,int st,int dr)
{
    v[nod]=-1;
    if (st==dr) arb[nod].f1=s[st]-48,arb[nod].s1=s[st]-48; else
    {
        int m=(st+dr)/2;
        build(nod*2,st,m);
        build(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void update(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        arb[nod].f1=(1LL*per*ss1[dr-st])%mod1;
        arb[nod].s1=(1LL*per*ss2[dr-st])%mod2;
        if (st!=dr) v[nod*2]=per,v[nod*2+1]=per;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) update(nod*2,st,m,x,y);
            if (y>m) update(nod*2+1,m+1,dr,x,y);
        lazypropagation(nod*2,st,m); lazypropagation(nod*2+1,m+1,dr);
        arb[nod].f1=(1LL*arb[nod*2].f1*pp1[dr-m]+arb[nod*2+1].f1)%mod1;
        arb[nod].s1=(1LL*arb[nod*2].s1*pp2[dr-m]+arb[nod*2+1].s1)%mod2;
    }
}
inline void query(int nod,int st,int dr,int x,int y)
{
    lazypropagation(nod,st,dr);
    if (st>=x && dr<=y) {
        sol.f1=(1LL*sol.f1*pp1[dr-st+1]+arb[nod].f1)%mod1;
        sol.s1=(1LL*sol.s1*pp2[dr-st+1]+arb[nod].s1)%mod2;
        return;
    } else
    {
        int m=(st+dr)/2;
        if (x<=m) query(nod*2,st,m,x,y);
            if (y>m) query(nod*2+1,m+1,dr,x,y);
    }
}
inline pii squery(int st,int dr)
{
    sol={0,0}; query(1,1,n,st,dr);
    return sol;
}
int main() {
scanf("%d %d %d",&n,&m,&k); gets(s);
gets(s+1);
pp1[0]=1; ss1[0]=1; pp2[0]=1; ss2[0]=1;
for (i=1;i<=n;i++) {
    pp1[i]=(1LL*pp1[i-1]*p)%mod1,ss1[i]=(1LL*ss1[i-1]*p+1)%mod1;
    pp2[i]=(1LL*pp2[i-1]*p)%mod2,ss2[i]=(1LL*ss2[i-1]*p+1)%mod2;
}
build(1,1,n);
for (i=1;i<=m+k;i++) {
    scanf("%d %d %d %d",&tip,&x,&y,&per);
    if (tip==1) update(1,1,n,x,y); else {
        if (y-x+1<=per) puts("YES"); else
        if (squery(x+per,y)==squery(x,y-per)) puts("YES"); else
            puts("NO");
    }
}
return 0;
}


/*****************************************************************
 *                   BISMILLAHIR RAHMANIR RAHIM                  *
 *          Raihat Zaman Neloy                                   *
 *          JU-CSE-21                                            *
 *          raihatneloy                                          *
 *****************************************************************/

#include<algorithm>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<list>
#include<iostream>
#include<fstream>
#include<numeric>
#include<string>
#include<vector>
#include<cstring>
#include<map>
#include<iterator>
#include<deque>
#include<climits>
#include<complex>

#define S scanf
#define P printf

#define  F(i,a,b) for(int i=a;i<b; i++)
#define FF(i,a,b) for(i=a;i<=b;i++)
#define FI(i,a,b) for((typeof(b)) i=a;i<=b;i++)
#define FR(i, a, b,inc) for(  i = (a); i <= (b); i+=inc )
#define RFR(i, a, b,dec) for(  i = (a); i >= (b); i-=dec )
#define FS(x) for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)
#define PR(x) for(typeof (x.begin()) it = x.begin(); it != x.end (); it++) cout << *it << " "; cout << endl;

#define LL long long int
#define ULL unsigned long long int
#define D double

#define Max(a,b)    (a>b?a:b)
#define Min(a,b)    (a<b?a:b)
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SQR(n)      (n*n)
#define PI          2.0*acos(0.0)

#define all(a) a.begin(),a.end()
#define X  first
#define Y  second
#define MP make_pair

#define PCC        cout<<"Case "<<cas++<<": ";
#define PC         printf("Case %d:",cas++);
#define PCN        printf("Case %d:\n",cas++);
#define NL         printf("\n");
#define cp         printf("here\n");

#define open       freopen("input.txt","r",stdin)
#define close      freopen ("output.txt","w",stdout)
#define Case(a)    printf("Case %d:",a)
#define caseh(a)   printf("Case #%d: ",a)
#define S1(a)      scanf("%d",&a)
#define S2(a,b)    scanf("%d%d",&a,&b)
#define S3(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define SL1(a)     scanf("%lld",&a)
#define SL2(a,b)   scanf("%lld%lld",&a,&b)
#define SL3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define CHR        getchar()
#define PB(x)      push_back(x)
#define pb         push_back
#define PP         pop_back()
#define PF(x)      push_front(x)
#define PPF(x)     pop_front()
#define PS(x)      push(x)
#define sz()       size()
#define UB         upper_bound
#define LB         lower_bound
#define mxe(a,n)   (*max_element(a,a+n))
#define mne(a,n)   (*min_element(a,a+n))
#define SUM(a,n)   (accumulate(a,a+n,0))
#define countbit(x) __builtin_popcount(x)
#define DBG(n)      P("Done %d\n",n);

// I/O
#define I(X)                       scanf("%d", &(X))
#define II(X, Y)                   scanf("%d%d", &(X), &(Y))
#define III(X, Y, Z)               scanf("%d%d%d", &(X), &(Y), &(Z))
#define DI(X) int (X);             scanf("%d", &X)
#define DII(X, Y) int X, Y;        scanf("%d%d", &X, &Y)
#define DIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)

#define ILL(X)          scanf("%lld", &(X))
#define DILL(X) LL (X); scanf("%lld", &X)

// LOOP
#define repv(i,a) for(int i=0;i<(int)a.size();i++)
#define revv(i,a) for(int i=((int)a.size())-1;i>=0;i--)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rev(i,a,b) for(int i=a;i>=b;i--)

#define FS(x) for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)

#define MEM(a,val) memset(a,val,sizeof(a));
#define SET(a)     memset(a,-1,sizeof a)
#define CLR(a)     memset(a,0,sizeof a)

using namespace std;

template <typename T> T BigMod (T b,T p,T m){if (p == 0) return 1;if (p%2 == 0){T s = BigMod(b,p/2,m);return ((s%m)*(s%m))%m;}return ((b%m)*(BigMod(b,p-1,m)%m))%m;}
template <typename T> T ModInv (T b,T m){return BigMod(b,m-2,m);}
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template <typename T> T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template <typename T> T Bigmod(T b,T p,T m){ if(p==0) return 1; else if (!(p&1)) return SQR(Bigmod(b,p/2,m)) % m;else return ((b % m) * Bigmod(b,p-1,m)) % m;}
template <typename T> T Dis(T x1,T y1,T x2, T y2){return sqrt( SQR(x1-x2) + SQR(y1-y2) );}
template <typename T> T Angle(T x1,T y1,T x2, T y2){ return atan( double(y1-y2) / double(x1-x2));}
template <typename T> T DIFF(T a,T b) { T d = a-b;if(d<0)return -d;else return d;}
template <typename T> T ABS(T a) {if(a<0)return -a;else return a;}
template <typename T> T gcd(T a,T b){if(a<0)return gcd(-a,b);if(b<0)return gcd(a,-b);return (b==0)?a:gcd(b,a%b);}
template <typename T> T lcm(T a,T b) {if(a<0)return lcm(-a,b);if(b<0)return lcm(a,-b);return a*(b/gcd(a,b));}
template <typename T> T euclide(T a,T b,T &x,T &y) {if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}
template <typename T> void ia (T a[],int n){for (int i=0; i<n; i++) cin >> a[i];}
template <typename T> void pa (T a[],int n){for (int i=0; i<n-1; i++) cout << a[i] << " ";cout << a[n-1] << endl;}
template <typename T> LL isLeft(T a,T b,T c) { return (a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y); }

int    Set(int N,int pos){ return N=N | (1<<pos);}
int  Reset(int N,int pos){return N= N & ~(1<<pos);}
bool Check(int N,int pos){return (bool)(N & (1<<pos));}
template< class T, class X > inline T   togglebit(T a, X i) { T t=1;return (a^(t<<i)); }

int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
int toLlint(string s) { long long int sm; stringstream ss(s); ss>>sm; return sm;}
int cdigittoint(char ch){return ch-'0';}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}

double DEG(double x) { return (180.0*x)/(PI);}
double RAD(double x) { return (x*(double)PI)/(180.0);}

#define VI  vector< int >
#define VII vector< VI >
#define VLL vector< LL >
#define PII pair< int , int >
#define PLL pair< LL , LL >
#define VPI vector< PII >

///         0123456789
#define MX  100007
#define MOD 1000000007
#define INF (1<<30)-1+(1<<30)
#define eps 1e-9

#define base ((1<<l)-1)
#define lft (idx<<1)
#define rgt (lft|1)
#define mid ((l+r)>>1)

/// Hashing Bases & MOD
///           0123456789
#define Base1 10000019LL
#define Base2 10000079LL
#define Base3 10000103LL
#define MOD1  1000000007LL
#define MOD2  1000000009LL
#define MOD3  1000000021LL
#define LOGX  17

LL B[2][MX];
LL M[2][MX];
LL Sum[2][4*MX],Tree[2][4*MX];
LL Mod[] = {MOD1,MOD3};
int Lazy[4*MX];

char s[MX];

void Init(){
    B[0][0] = B[1][0] = 1;

    for (int i=1;i<MX;i++){
        B[0][i] = (B[0][i-1] * Base1) % MOD1;
        B[1][i] = (B[1][i-1] * Base3) % MOD3;

        M[0][i] = ModInv( B[0][i] , MOD1 );
        M[1][i] = ModInv( B[1][i] , MOD3 );
    }
}

void Build(int idx,int l,int r){
    Lazy[idx] = -1;

    if (l == r){
        for (int i=0;i<2;i++){
            Sum[i][idx] = B[i][l];
            Tree[i][idx] = (( s[l]-'0'+1 ) * Sum[i][idx])%Mod[i];
        }

        return ;
    }

    Build(lft,l,mid);
    Build(rgt,mid+1,r);

    rep(i,0,1)  Sum[i][idx] = (Sum[i][lft] + Sum[i][rgt])%Mod[i], Tree[i][idx] = (Tree[i][lft] + Tree[i][rgt])%Mod[i];
}

void Propagate(int idx,int v){
    Lazy[idx] = v;

    rep(i,0,1)   Tree[i][idx] = ( v * Sum[i][idx] ) % Mod[i];
}

void Update(int idx,int l,int r,int s,int e,int v){
    if (l == s && r == e){
        Propagate(idx,v);
        return ;
    }

    if (Lazy[idx] != -1){
        Propagate(lft,Lazy[idx]);
        Propagate(rgt,Lazy[idx]);
        Lazy[idx] = -1;
    }

    if (e <= mid)       Update(lft,l,mid,s,e,v);
    else if (s > mid)   Update(rgt,mid+1,r,s,e,v);
    else                Update(lft,l,mid,s,mid,v), Update(rgt,mid+1,r,mid+1,e,v);

    rep(i,0,1)          Tree[i][idx] = ( Tree[i][lft] + Tree[i][rgt] )% Mod[i];
}

PLL Query(int idx,int l,int r,int s,int e){
    if ( l == s && r == e ){
        LL p[2];

        rep(i,0,1)  p[i] = ( Tree[i][idx] * M[i][l] ) % Mod[i];

        return MP( p[0],p[1] );
    }

    if ( Lazy[idx] != -1 ){
        Propagate(lft,Lazy[idx]);
        Propagate(rgt,Lazy[idx]);
        Lazy[idx] = -1;
    }

    if (e <= mid)       return Query(lft,l,mid,s,e);
    else if (s > mid)   return Query(rgt,mid+1,r,s,e);
    else{
        PLL q1 = Query(lft,l,mid,s,mid);
        PLL q2 = Query(rgt,mid+1,r,mid+1,e);

        LL p[2];

        p[0] = (q1.X + ( q2.X * B[0][mid+1-s] ))%Mod[0];
        p[1] = (q1.Y + ( q2.Y * B[1][mid+1-s] ))%Mod[1];

        return MP( p[0],p[1] );
    }
}

int main(){
    Init();

    DIII(n,m,k);

    S("%s",s+1);

    Build(1,1,n);

    rep(i,1,m+k){
        DI(cs);
        DIII(l,r,x);

        if (cs == 1)    Update(1,1,n,l,r,x+1);
        else{
            if (x > (r-l))    { puts("YES"); continue; }
            if (x > (r-l+1)/2){ puts("NO"); continue; }

            PLL q1 = Query(1,1,n,l,r-x);
            PLL q2 = Query(1,1,n,l+x,r);

            //cout << q1.X << " == " << q2.X << endl;
            //cout << q1.Y << " == " << q2.Y << endl;

            if (q1 == q2)   puts("YES");
            else            puts("NO");
        }
    }
return 0;
}


/*****************************************************************
 *                   BISMILLAHIR RAHMANIR RAHIM                  *
 *          Raihat Zaman Neloy                                   *
 *          JU-CSE-21                                            *
 *          raihatneloy                                          *
 *****************************************************************/

#include<algorithm>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<list>
#include<iostream>
#include<fstream>
#include<numeric>
#include<string>
#include<vector>
#include<cstring>
#include<map>
#include<iterator>
#include<deque>
#include<climits>
#include<complex>

#define S scanf
#define P printf

#define  F(i,a,b) for(int i=a;i<b; i++)
#define FF(i,a,b) for(i=a;i<=b;i++)
#define FI(i,a,b) for((typeof(b)) i=a;i<=b;i++)
#define FR(i, a, b,inc) for(  i = (a); i <= (b); i+=inc )
#define RFR(i, a, b,dec) for(  i = (a); i >= (b); i-=dec )
#define FS(x) for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)
#define PR(x) for(typeof (x.begin()) it = x.begin(); it != x.end (); it++) cout << *it << " "; cout << endl;

#define LL long long int
#define ULL unsigned long long int
#define D double

#define Max(a,b)    (a>b?a:b)
#define Min(a,b)    (a<b?a:b)
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SQR(n)      (n*n)
#define PI          2.0*acos(0.0)

#define all(a) a.begin(),a.end()
#define X  first
#define Y  second
#define MP make_pair

#define PCC        cout<<"Case "<<cas++<<": ";
#define PC         printf("Case %d:",cas++);
#define PCN        printf("Case %d:\n",cas++);
#define NL         printf("\n");
#define cp         printf("here\n");

#define open       freopen("input.txt","r",stdin)
#define close      freopen ("output.txt","w",stdout)
#define Case(a)    printf("Case %d:",a)
#define caseh(a)   printf("Case #%d: ",a)
#define S1(a)      scanf("%d",&a)
#define S2(a,b)    scanf("%d%d",&a,&b)
#define S3(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define SL1(a)     scanf("%lld",&a)
#define SL2(a,b)   scanf("%lld%lld",&a,&b)
#define SL3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define CHR        getchar()
#define PB(x)      push_back(x)
#define pb         push_back
#define PP         pop_back()
#define PF(x)      push_front(x)
#define PPF(x)     pop_front()
#define PS(x)      push(x)
#define sz()       size()
#define UB         upper_bound
#define LB         lower_bound
#define mxe(a,n)   (*max_element(a,a+n))
#define mne(a,n)   (*min_element(a,a+n))
#define SUM(a,n)   (accumulate(a,a+n,0))
#define countbit(x) __builtin_popcount(x)
#define DBG(n)      P("Done %d\n",n);

// I/O
#define I(X)                       scanf("%d", &(X))
#define II(X, Y)                   scanf("%d%d", &(X), &(Y))
#define III(X, Y, Z)               scanf("%d%d%d", &(X), &(Y), &(Z))
#define DI(X) int (X);             scanf("%d", &X)
#define DII(X, Y) int X, Y;        scanf("%d%d", &X, &Y)
#define DIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)

#define ILL(X)          scanf("%lld", &(X))
#define DILL(X) LL (X); scanf("%lld", &X)

// LOOP
#define repv(i,a) for(int i=0;i<(int)a.size();i++)
#define revv(i,a) for(int i=((int)a.size())-1;i>=0;i--)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rev(i,a,b) for(int i=a;i>=b;i--)

#define FS(x) for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)

#define MEM(a,val) memset(a,val,sizeof(a));
#define SET(a)     memset(a,-1,sizeof a)
#define CLR(a)     memset(a,0,sizeof a)

using namespace std;

template <typename T> T BigMod (T b,T p,T m){if (p == 0) return 1;if (p%2 == 0){T s = BigMod(b,p/2,m);return ((s%m)*(s%m))%m;}return ((b%m)*(BigMod(b,p-1,m)%m))%m;}
template <typename T> T ModInv (T b,T m){return BigMod(b,m-2,m);}
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template <typename T> T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template <typename T> T Bigmod(T b,T p,T m){ if(p==0) return 1; else if (!(p&1)) return SQR(Bigmod(b,p/2,m)) % m;else return ((b % m) * Bigmod(b,p-1,m)) % m;}
template <typename T> T Dis(T x1,T y1,T x2, T y2){return sqrt( SQR(x1-x2) + SQR(y1-y2) );}
template <typename T> T Angle(T x1,T y1,T x2, T y2){ return atan( double(y1-y2) / double(x1-x2));}
template <typename T> T DIFF(T a,T b) { T d = a-b;if(d<0)return -d;else return d;}
template <typename T> T ABS(T a) {if(a<0)return -a;else return a;}
template <typename T> T gcd(T a,T b){if(a<0)return gcd(-a,b);if(b<0)return gcd(a,-b);return (b==0)?a:gcd(b,a%b);}
template <typename T> T lcm(T a,T b) {if(a<0)return lcm(-a,b);if(b<0)return lcm(a,-b);return a*(b/gcd(a,b));}
template <typename T> T euclide(T a,T b,T &x,T &y) {if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}
template <typename T> void ia (T a[],int n){for (int i=0; i<n; i++) cin >> a[i];}
template <typename T> void pa (T a[],int n){for (int i=0; i<n-1; i++) cout << a[i] << " ";cout << a[n-1] << endl;}
template <typename T> LL isLeft(T a,T b,T c) { return (a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y); }

int    Set(int N,int pos){ return N=N | (1<<pos);}
int  Reset(int N,int pos){return N= N & ~(1<<pos);}
bool Check(int N,int pos){return (bool)(N & (1<<pos));}
template< class T, class X > inline T   togglebit(T a, X i) { T t=1;return (a^(t<<i)); }

int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
int toLlint(string s) { long long int sm; stringstream ss(s); ss>>sm; return sm;}
int cdigittoint(char ch){return ch-'0';}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}

double DEG(double x) { return (180.0*x)/(PI);}
double RAD(double x) { return (x*(double)PI)/(180.0);}

#define VI  vector< int >
#define VII vector< VI >
#define VLL vector< LL >
#define PII pair< int , int >
#define PLL pair< LL , LL >
#define VPI vector< PII >

///         0123456789
#define MX  100007
#define MOD 1000000007
#define INF (1<<30)-1+(1<<30)
#define eps 1e-9

#define base ((1<<l)-1)
#define lft (idx<<1)
#define rgt (lft|1)
#define mid ((l+r)>>1)

/// Hashing Bases & MOD
///           0123456789
#define Base1 10000019LL
#define Base2 10000079LL
#define Base3 10000103LL
#define MOD1  1000000007LL
#define MOD2  1000000009LL
#define MOD3  1000000021LL
#define LOGX  17

LL B[2][MX];
LL M[2][MX];
LL Sum[2][4*MX],Tree[2][4*MX];
LL Mod[] = {MOD1,MOD2};
int Lazy[4*MX];

char s[MX];

void Init(){
    B[0][0] = B[1][0] = 1;

    for (int i=1;i<MX;i++){
        B[0][i] = (B[0][i-1] * Base1) % MOD1;
        B[1][i] = (B[1][i-1] * Base2) % MOD2;

        M[0][i] = ModInv( B[0][i] , MOD1 );
        M[1][i] = ModInv( B[1][i] , MOD2 );
    }
}

void Build(int idx,int l,int r){
    Lazy[idx] = -1;

    if (l == r){
        for (int i=0;i<2;i++){
            Sum[i][idx] = B[i][l];
            Tree[i][idx] = (( s[l]-'0'+1 ) * Sum[i][idx])%Mod[i];
        }

        return ;
    }

    Build(lft,l,mid);
    Build(rgt,mid+1,r);

    rep(i,0,1)  Sum[i][idx] = (Sum[i][lft] + Sum[i][rgt])%Mod[i], Tree[i][idx] = (Tree[i][lft] + Tree[i][rgt])%Mod[i];
}

void Propagate(int idx,int v){
    Lazy[idx] = v;

    rep(i,0,1)   Tree[i][idx] = ( v * Sum[i][idx] ) % Mod[i];
}

void Update(int idx,int l,int r,int s,int e,int v){
    if (l == s && r == e){
        Propagate(idx,v);
        return ;
    }

    if (Lazy[idx] != -1){
        Propagate(lft,Lazy[idx]);
        Propagate(rgt,Lazy[idx]);
        Lazy[idx] = -1;
    }

    if (e <= mid)       Update(lft,l,mid,s,e,v);
    else if (s > mid)   Update(rgt,mid+1,r,s,e,v);
    else                Update(lft,l,mid,s,mid,v), Update(rgt,mid+1,r,mid+1,e,v);

    rep(i,0,1)          Tree[i][idx] = ( Tree[i][lft] + Tree[i][rgt] )% Mod[i];
}

PLL Query(int idx,int l,int r,int s,int e){
    if ( l == s && r == e ){
        LL p[2];

        rep(i,0,1)  p[i] = ( Tree[i][idx] * M[i][l] ) % Mod[i];

        return MP( p[0],p[1] );
    }

    if ( Lazy[idx] != -1 ){
        Propagate(lft,Lazy[idx]);
        Propagate(rgt,Lazy[idx]);
        Lazy[idx] = -1;
    }

    if (e <= mid)       return Query(lft,l,mid,s,e);
    else if (s > mid)   return Query(rgt,mid+1,r,s,e);
    else{
        PLL q1 = Query(lft,l,mid,s,mid);
        PLL q2 = Query(rgt,mid+1,r,mid+1,e);

        LL p[2];

        p[0] = (q1.X + ( q2.X * B[0][mid+1-s] ))%Mod[0];
        p[1] = (q1.Y + ( q2.Y * B[1][mid+1-s] ))%Mod[1];

        return MP( p[0],p[1] );
    }
}

int main(){
    Init();

    DIII(n,m,k);

    S("%s",s+1);

    Build(1,1,n);

    rep(i,1,m+k){
        DI(cs);
        DIII(l,r,x);

        if (cs == 1)    Update(1,1,n,l,r,x+1);
        else{
            if (x > r-l)    { puts("NO"); continue; }

            PLL q1 = Query(1,1,n,l,r-x);
            PLL q2 = Query(1,1,n,l+x,r);

            //cout << q1.X << " == " << q2.X << endl;
            //cout << q1.Y << " == " << q2.Y << endl;

            if (q1 == q2)   puts("YES");
            else            puts("NO");
        }
    }
return 0;
}


/*****************************************************************
 *                   BISMILLAHIR RAHMANIR RAHIM                  *
 *          Raihat Zaman Neloy                                   *
 *          JU-CSE-21                                            *
 *          raihatneloy                                          *
 *****************************************************************/

#include<algorithm>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<list>
#include<iostream>
#include<fstream>
#include<numeric>
#include<string>
#include<vector>
#include<cstring>
#include<map>
#include<iterator>
#include<deque>
#include<climits>
#include<complex>

#define S scanf
#define P printf

#define  F(i,a,b) for(int i=a;i<b; i++)
#define FF(i,a,b) for(i=a;i<=b;i++)
#define FI(i,a,b) for((typeof(b)) i=a;i<=b;i++)
#define FR(i, a, b,inc) for(  i = (a); i <= (b); i+=inc )
#define RFR(i, a, b,dec) for(  i = (a); i >= (b); i-=dec )
#define FS(x) for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)
#define PR(x) for(typeof (x.begin()) it = x.begin(); it != x.end (); it++) cout << *it << " "; cout << endl;

#define LL long long int
#define ULL unsigned long long int
#define D double

#define Max(a,b)    (a>b?a:b)
#define Min(a,b)    (a<b?a:b)
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SQR(n)      (n*n)
#define PI          2.0*acos(0.0)

#define all(a) a.begin(),a.end()
#define X  first
#define Y  second
#define MP make_pair

#define PCC        cout<<"Case "<<cas++<<": ";
#define PC         printf("Case %d:",cas++);
#define PCN        printf("Case %d:\n",cas++);
#define NL         printf("\n");
#define cp         printf("here\n");

#define open       freopen("input.txt","r",stdin)
#define close      freopen ("output.txt","w",stdout)
#define Case(a)    printf("Case %d:",a)
#define caseh(a)   printf("Case #%d: ",a)
#define S1(a)      scanf("%d",&a)
#define S2(a,b)    scanf("%d%d",&a,&b)
#define S3(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define SL1(a)     scanf("%lld",&a)
#define SL2(a,b)   scanf("%lld%lld",&a,&b)
#define SL3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define CHR        getchar()
#define PB(x)      push_back(x)
#define pb         push_back
#define PP         pop_back()
#define PF(x)      push_front(x)
#define PPF(x)     pop_front()
#define PS(x)      push(x)
#define sz()       size()
#define UB         upper_bound
#define LB         lower_bound
#define mxe(a,n)   (*max_element(a,a+n))
#define mne(a,n)   (*min_element(a,a+n))
#define SUM(a,n)   (accumulate(a,a+n,0))
#define countbit(x) __builtin_popcount(x)
#define DBG(n)      P("Done %d\n",n);

// I/O
#define I(X)                       scanf("%d", &(X))
#define II(X, Y)                   scanf("%d%d", &(X), &(Y))
#define III(X, Y, Z)               scanf("%d%d%d", &(X), &(Y), &(Z))
#define DI(X) int (X);             scanf("%d", &X)
#define DII(X, Y) int X, Y;        scanf("%d%d", &X, &Y)
#define DIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)

#define ILL(X)          scanf("%lld", &(X))
#define DILL(X) LL (X); scanf("%lld", &X)

// LOOP
#define repv(i,a) for(int i=0;i<(int)a.size();i++)
#define revv(i,a) for(int i=((int)a.size())-1;i>=0;i--)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rev(i,a,b) for(int i=a;i>=b;i--)

#define FS(x) for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)

#define MEM(a,val) memset(a,val,sizeof(a));
#define SET(a)     memset(a,-1,sizeof a)
#define CLR(a)     memset(a,0,sizeof a)

using namespace std;

template <typename T> T BigMod (T b,T p,T m){if (p == 0) return 1;if (p%2 == 0){T s = BigMod(b,p/2,m);return ((s%m)*(s%m))%m;}return ((b%m)*(BigMod(b,p-1,m)%m))%m;}
template <typename T> T ModInv (T b,T m){return BigMod(b,m-2,m);}
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template <typename T> T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template <typename T> T Bigmod(T b,T p,T m){ if(p==0) return 1; else if (!(p&1)) return SQR(Bigmod(b,p/2,m)) % m;else return ((b % m) * Bigmod(b,p-1,m)) % m;}
template <typename T> T Dis(T x1,T y1,T x2, T y2){return sqrt( SQR(x1-x2) + SQR(y1-y2) );}
template <typename T> T Angle(T x1,T y1,T x2, T y2){ return atan( double(y1-y2) / double(x1-x2));}
template <typename T> T DIFF(T a,T b) { T d = a-b;if(d<0)return -d;else return d;}
template <typename T> T ABS(T a) {if(a<0)return -a;else return a;}
template <typename T> T gcd(T a,T b){if(a<0)return gcd(-a,b);if(b<0)return gcd(a,-b);return (b==0)?a:gcd(b,a%b);}
template <typename T> T lcm(T a,T b) {if(a<0)return lcm(-a,b);if(b<0)return lcm(a,-b);return a*(b/gcd(a,b));}
template <typename T> T euclide(T a,T b,T &x,T &y) {if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}
template <typename T> void ia (T a[],int n){for (int i=0; i<n; i++) cin >> a[i];}
template <typename T> void pa (T a[],int n){for (int i=0; i<n-1; i++) cout << a[i] << " ";cout << a[n-1] << endl;}
template <typename T> LL isLeft(T a,T b,T c) { return (a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y); }

int    Set(int N,int pos){ return N=N | (1<<pos);}
int  Reset(int N,int pos){return N= N & ~(1<<pos);}
bool Check(int N,int pos){return (bool)(N & (1<<pos));}
template< class T, class X > inline T   togglebit(T a, X i) { T t=1;return (a^(t<<i)); }

int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
int toLlint(string s) { long long int sm; stringstream ss(s); ss>>sm; return sm;}
int cdigittoint(char ch){return ch-'0';}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}

double DEG(double x) { return (180.0*x)/(PI);}
double RAD(double x) { return (x*(double)PI)/(180.0);}

#define VI  vector< int >
#define VII vector< VI >
#define VLL vector< LL >
#define PII pair< int , int >
#define PLL pair< LL , LL >
#define VPI vector< PII >

///         0123456789
#define MX  100007
#define MOD 1000000007
#define INF (1<<30)-1+(1<<30)
#define eps 1e-9

#define base ((1<<l)-1)
#define lft (idx<<1)
#define rgt (lft|1)
#define mid ((l+r)>>1)

/// Hashing Bases & MOD
///           0123456789
#define Base1 10000019LL
#define Base2 10000079LL
#define Base3 10000103LL
#define MOD1  1000000007LL
#define MOD2  1000000009LL
#define MOD3  1000000021LL
#define LOGX  17

LL B[2][MX];
LL M[2][MX];
LL Sum[2][4*MX],Tree[2][4*MX];
LL Mod[] = {MOD1,MOD3};
int Lazy[4*MX];

char s[MX];

void Init(){
    B[0][0] = B[1][0] = 1;

    for (int i=1;i<MX;i++){
        B[0][i] = (B[0][i-1] * Base1) % MOD1;
        B[1][i] = (B[1][i-1] * Base3) % MOD3;

        M[0][i] = ModInv( B[0][i] , MOD1 );
        M[1][i] = ModInv( B[1][i] , MOD3 );
    }
}

void Build(int idx,int l,int r){
    Lazy[idx] = -1;

    if (l == r){
        for (int i=0;i<2;i++){
            Sum[i][idx] = B[i][l];
            Tree[i][idx] = (( s[l]-'0'+1 ) * Sum[i][idx])%Mod[i];
        }

        return ;
    }

    Build(lft,l,mid);
    Build(rgt,mid+1,r);

    rep(i,0,1)  Sum[i][idx] = (Sum[i][lft] + Sum[i][rgt])%Mod[i], Tree[i][idx] = (Tree[i][lft] + Tree[i][rgt])%Mod[i];
}

void Propagate(int idx,int v){
    Lazy[idx] = v;

    rep(i,0,1)   Tree[i][idx] = ( v * Sum[i][idx] ) % Mod[i];
}

void Update(int idx,int l,int r,int s,int e,int v){
    if (l == s && r == e){
        Propagate(idx,v);
        return ;
    }

    if (Lazy[idx] != -1){
        Propagate(lft,Lazy[idx]);
        Propagate(rgt,Lazy[idx]);
        Lazy[idx] = -1;
    }

    if (e <= mid)       Update(lft,l,mid,s,e,v);
    else if (s > mid)   Update(rgt,mid+1,r,s,e,v);
    else                Update(lft,l,mid,s,mid,v), Update(rgt,mid+1,r,mid+1,e,v);

    rep(i,0,1)          Tree[i][idx] = ( Tree[i][lft] + Tree[i][rgt] )% Mod[i];
}

PLL Query(int idx,int l,int r,int s,int e){
    if ( l == s && r == e ){
        LL p[2];

        rep(i,0,1)  p[i] = ( Tree[i][idx] * M[i][l] ) % Mod[i];

        return MP( p[0],p[1] );
    }

    if ( Lazy[idx] != -1 ){
        Propagate(lft,Lazy[idx]);
        Propagate(rgt,Lazy[idx]);
        Lazy[idx] = -1;
    }

    if (e <= mid)       return Query(lft,l,mid,s,e);
    else if (s > mid)   return Query(rgt,mid+1,r,s,e);
    else{
        PLL q1 = Query(lft,l,mid,s,mid);
        PLL q2 = Query(rgt,mid+1,r,mid+1,e);

        LL p[2];

        p[0] = (q1.X + ( q2.X * B[0][mid+1-s] ))%Mod[0];
        p[1] = (q1.Y + ( q2.Y * B[1][mid+1-s] ))%Mod[1];

        return MP( p[0],p[1] );
    }
}

int main(){
    Init();

    DIII(n,m,k);

    S("%s",s+1);

    Build(1,1,n);

    rep(i,1,m+k){
        DI(cs);
        DIII(l,r,x);

        if (cs == 1)    Update(1,1,n,l,r,x+1);
        else{
            if (x > (r-l))    { puts("YES"); continue; }

            PLL q1 = Query(1,1,n,l,r-x);
            PLL q2 = Query(1,1,n,l+x,r);

            //cout << q1.X << " == " << q2.X << endl;
            //cout << q1.Y << " == " << q2.Y << endl;

            if (q1 == q2)   puts("YES");
            else            puts("NO");
        }
    }
return 0;
}


/*****************************************************************
 *                   BISMILLAHIR RAHMANIR RAHIM                  *
 *          Raihat Zaman Neloy                                   *
 *          JU-CSE-21                                            *
 *          raihatneloy                                          *
 *****************************************************************/

#include<algorithm>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<list>
#include<iostream>
#include<fstream>
#include<numeric>
#include<string>
#include<vector>
#include<cstring>
#include<map>
#include<iterator>
#include<deque>
#include<climits>
#include<complex>

#define S scanf
#define P printf

#define  F(i,a,b) for(int i=a;i<b; i++)
#define FF(i,a,b) for(i=a;i<=b;i++)
#define FI(i,a,b) for((typeof(b)) i=a;i<=b;i++)
#define FR(i, a, b,inc) for(  i = (a); i <= (b); i+=inc )
#define RFR(i, a, b,dec) for(  i = (a); i >= (b); i-=dec )
#define FS(x) for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)
#define PR(x) for(typeof (x.begin()) it = x.begin(); it != x.end (); it++) cout << *it << " "; cout << endl;

#define LL long long int
#define ULL unsigned long long int
#define D double

#define Max(a,b)    (a>b?a:b)
#define Min(a,b)    (a<b?a:b)
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SQR(n)      (n*n)
#define PI          2.0*acos(0.0)

#define all(a) a.begin(),a.end()
#define X  first
#define Y  second
#define MP make_pair

#define PCC        cout<<"Case "<<cas++<<": ";
#define PC         printf("Case %d:",cas++);
#define PCN        printf("Case %d:\n",cas++);
#define NL         printf("\n");
#define cp         printf("here\n");

#define open       freopen("input.txt","r",stdin)
#define close      freopen ("output.txt","w",stdout)
#define Case(a)    printf("Case %d:",a)
#define caseh(a)   printf("Case #%d: ",a)
#define S1(a)      scanf("%d",&a)
#define S2(a,b)    scanf("%d%d",&a,&b)
#define S3(a,b,c)  scanf("%d%d%d",&a,&b,&c)
#define SL1(a)     scanf("%lld",&a)
#define SL2(a,b)   scanf("%lld%lld",&a,&b)
#define SL3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define CHR        getchar()
#define PB(x)      push_back(x)
#define pb         push_back
#define PP         pop_back()
#define PF(x)      push_front(x)
#define PPF(x)     pop_front()
#define PS(x)      push(x)
#define sz()       size()
#define UB         upper_bound
#define LB         lower_bound
#define mxe(a,n)   (*max_element(a,a+n))
#define mne(a,n)   (*min_element(a,a+n))
#define SUM(a,n)   (accumulate(a,a+n,0))
#define countbit(x) __builtin_popcount(x)
#define DBG(n)      P("Done %d\n",n);

// I/O
#define I(X)                       scanf("%d", &(X))
#define II(X, Y)                   scanf("%d%d", &(X), &(Y))
#define III(X, Y, Z)               scanf("%d%d%d", &(X), &(Y), &(Z))
#define DI(X) int (X);             scanf("%d", &X)
#define DII(X, Y) int X, Y;        scanf("%d%d", &X, &Y)
#define DIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)

#define ILL(X)          scanf("%lld", &(X))
#define DILL(X) LL (X); scanf("%lld", &X)

// LOOP
#define repv(i,a) for(int i=0;i<(int)a.size();i++)
#define revv(i,a) for(int i=((int)a.size())-1;i>=0;i--)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rev(i,a,b) for(int i=a;i>=b;i--)

#define FS(x) for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)

#define MEM(a,val) memset(a,val,sizeof(a));
#define SET(a)     memset(a,-1,sizeof a)
#define CLR(a)     memset(a,0,sizeof a)

using namespace std;

template <typename T> T BigMod (T b,T p,T m){if (p == 0) return 1;if (p%2 == 0){T s = BigMod(b,p/2,m);return ((s%m)*(s%m))%m;}return ((b%m)*(BigMod(b,p-1,m)%m))%m;}
template <typename T> T ModInv (T b,T m){return BigMod(b,m-2,m);}
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template <typename T> T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template <typename T> T Bigmod(T b,T p,T m){ if(p==0) return 1; else if (!(p&1)) return SQR(Bigmod(b,p/2,m)) % m;else return ((b % m) * Bigmod(b,p-1,m)) % m;}
template <typename T> T Dis(T x1,T y1,T x2, T y2){return sqrt( SQR(x1-x2) + SQR(y1-y2) );}
template <typename T> T Angle(T x1,T y1,T x2, T y2){ return atan( double(y1-y2) / double(x1-x2));}
template <typename T> T DIFF(T a,T b) { T d = a-b;if(d<0)return -d;else return d;}
template <typename T> T ABS(T a) {if(a<0)return -a;else return a;}
template <typename T> T gcd(T a,T b){if(a<0)return gcd(-a,b);if(b<0)return gcd(a,-b);return (b==0)?a:gcd(b,a%b);}
template <typename T> T lcm(T a,T b) {if(a<0)return lcm(-a,b);if(b<0)return lcm(a,-b);return a*(b/gcd(a,b));}
template <typename T> T euclide(T a,T b,T &x,T &y) {if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}
template <typename T> void ia (T a[],int n){for (int i=0; i<n; i++) cin >> a[i];}
template <typename T> void pa (T a[],int n){for (int i=0; i<n-1; i++) cout << a[i] << " ";cout << a[n-1] << endl;}
template <typename T> LL isLeft(T a,T b,T c) { return (a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y); }

int    Set(int N,int pos){ return N=N | (1<<pos);}
int  Reset(int N,int pos){return N= N & ~(1<<pos);}
bool Check(int N,int pos){return (bool)(N & (1<<pos));}
template< class T, class X > inline T   togglebit(T a, X i) { T t=1;return (a^(t<<i)); }

int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
int toLlint(string s) { long long int sm; stringstream ss(s); ss>>sm; return sm;}
int cdigittoint(char ch){return ch-'0';}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}

double DEG(double x) { return (180.0*x)/(PI);}
double RAD(double x) { return (x*(double)PI)/(180.0);}

#define VI  vector< int >
#define VII vector< VI >
#define VLL vector< LL >
#define PII pair< int , int >
#define PLL pair< LL , LL >
#define PUL pair< ULL , ULL >
#define VPI vector< PII >

///         0123456789
#define MX  100007
#define MOD 1000000007
#define INF (1<<30)-1+(1<<30)
#define eps 1e-9

#define base ((1<<l)-1)
#define lft (idx<<1)
#define rgt (lft|1)
#define mid ((l+r)>>1)

/// Hashing Bases & MOD
///           0123456789
#define Base1 10000019LL
#define Base2 10000079LL
#define Base3 10000103LL
#define MOD1  1000000007LL
#define MOD2  1000000009LL
#define MOD3  1000000021LL
#define LOGX  17

ULL B1[MX],B2[MX];
ULL S1[MX],S2[MX];
ULL Tree[2][4*MX];
int Lazy[4*MX];
char s[MX];

void Init(){
    B1[0] = B2[0] = S1[0] = S2[0] = 1;

    for (int i=1;i<MX;i++){
        B1[i] = B1[i-1] * Base1;
        B2[i] = B2[i-1] * Base2;

        S1[i] = S1[i-1] + B1[i];
        S2[i] = S2[i-1] + B2[i];
    }
}

void Propagate(int idx,int l,int r,int v){
    Lazy[idx] = v;

    Tree[0][idx] = v * S1[r-l];
    Tree[1][idx] = v * S2[r-l];
}

void Update(int idx,int l,int r,int s,int e,int v){
    if (l == s && r == e){
        Propagate(idx,l,r,v);
        return;
    }

    if (Lazy[idx]){
        Propagate(lft,l,mid,Lazy[idx]);
        Propagate(rgt,mid+1,r,Lazy[idx]);
        Lazy[idx] = 0;
    }

    if (e <= mid)       Update(lft,l,mid,s,e,v);
    else if (s > mid)   Update(rgt,mid+1,r,s,e,v);
    else                Update(lft,l,mid,s,mid,v),Update(rgt,mid+1,r,mid+1,e,v);

    Tree[0][idx] = Tree[0][lft] + B1[mid+1-l]*Tree[0][rgt];
    Tree[1][idx] = Tree[1][rgt] + B2[mid+1-l]*Tree[1][rgt];
}

PUL Query(int idx,int l,int r,int s,int e){
    if (l == s && r == e)       return MP( Tree[0][idx],Tree[1][idx] );

    if (Lazy[idx]){
        Propagate(lft,l,mid,Lazy[idx]);
        Propagate(rgt,mid+1,r,Lazy[idx]);
        Lazy[idx] = 0;
    }

    if (e <= mid)               return Query(lft,l,mid,s,e);
    else if (s > mid)           return Query(rgt,mid+1,r,s,e);
    else {
        PUL q1 = Query(lft,l,mid,s,mid);
        PUL q2 = Query(rgt,mid+1,r,mid+1,e);

        PUL q;

        q.X = q1.X + B1[mid+1-s]*q2.X;
        q.Y = q1.Y + B2[mid+1-s]*q2.Y;

        return q;
    }
}

int main(){
    Init();

    DIII(n,m,k);

    S("%s",s+1);

    for (int i=1;i<=n;i++)      Update(1,1,n,i,i,s[i]-'0'+1);

    rep(i,1,m+k){
        DI(cs);
        DIII(l,r,x);

        if (cs == 1)    Update(1,1,n,l,r,x+1);
        else{
            if (x > (r-l))    { puts("YES"); continue; }
            if (x > (r-l+2)/2){ puts("NO"); continue; }

            PUL q1 = Query(1,1,n,l,r-x);
            PUL q2 = Query(1,1,n,l+x,r);

            //cout << q1.X << " == " << q2.X << endl;
            //cout << q1.Y << " == " << q2.Y << endl;

            if (q1 == q2)   puts("YES");
            else            puts("NO");
        }
    }
return 0;
}