线段树维护哈希值。
预处理一个数组,val[i][j]表示:全是i,长为j的哈希值。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N= 1e5 + 5 , base= 131 , MOD= 1e9 + 7 ;
int n, m, k, q;
int a[ N] , sum[ N<< 2 ] , tag[ N<< 2 ] ;
int bin[ N] , val[ 10 ] [ N] ;
inline void init ( )
{
bin[ 0 ] = 1 ;
for ( register int i= 1 ; i<= n; ++ i) bin[ i] = ( bin[ i- 1 ] * base) % MOD;
for ( register int i= 0 ; i<= 9 ; ++ i)
for ( register int j= 1 ; j<= n; ++ j) val[ i] [ j] = ( val[ i] [ j- 1 ] * base% MOD+ i) % MOD;
}
void build ( int k, int l, int r)
{
if ( l== r)
{
sum[ k] = val[ a[ l] ] [ 1 ] ;
return ;
}
int mid= l+ r>> 1 ;
build ( k<< 1 , l, mid) ;
build ( k<< 1 | 1 , mid+ 1 , r) ;
sum[ k] = ( sum[ k<< 1 ] * bin[ r- ( mid+ 1 ) + 1 ] % MOD+ sum[ k<< 1 | 1 ] ) % MOD;
}
inline void pushdown ( int k, int l, int r, int mid)
{
if ( ~ tag[ k] )
{
tag[ k<< 1 ] = tag[ k<< 1 | 1 ] = tag[ k] ;
sum[ k<< 1 ] = val[ tag[ k] ] [ mid- l+ 1 ] ;
sum[ k<< 1 | 1 ] = val[ tag[ k] ] [ r- ( mid+ 1 ) + 1 ] ;
tag[ k] = - 1 ;
}
}
void change ( int k, int l, int r, int qx, int qy, int v)
{
if ( qx== l && r== qy)
{
sum[ k] = val[ v] [ r- l+ 1 ] ;
tag[ k] = v;
return ;
}
int mid= l+ r>> 1 ;
pushdown ( k, l, r, mid) ;
if ( qx<= mid && mid< qy)
{
change ( k<< 1 , l, mid, qx, mid, v) ;
change ( k<< 1 | 1 , mid+ 1 , r, mid+ 1 , qy, v) ;
}
else if ( qx<= mid) change ( k<< 1 , l, mid, qx, qy, v) ;
else if ( mid< qy) change ( k<< 1 | 1 , mid+ 1 , r, qx, qy, v) ;
sum[ k] = ( sum[ k<< 1 ] * bin[ r- ( mid+ 1 ) + 1 ] % MOD+ sum[ k<< 1 | 1 ] ) % MOD;
}
int query ( int k, int l, int r, int qx, int qy)
{
if ( qx== l && r== qy) return sum[ k] ;
int mid= l+ r>> 1 ;
pushdown ( k, l, r, mid) ;
if ( qx<= mid && mid< qy)
return ( query ( k<< 1 , l, mid, qx, mid) * bin[ qy- ( mid+ 1 ) + 1 ] % MOD+ query ( k<< 1 | 1 , mid+ 1 , r, mid+ 1 , qy) ) % MOD;
if ( qx<= mid) return query ( k<< 1 , l, mid, qx, qy) ;
if ( mid< qy) return query ( k<< 1 | 1 , mid+ 1 , r, qx, qy) ;
}
signed main ( ) {
memset ( tag, - 1 , sizeof ( tag) ) ;
scanf ( "%lld%lld%lld" , & n, & m, & k) ; q= m+ k;
init ( ) ;
for ( register int i= 1 ; i<= n; ++ i) scanf ( "%1lld" , & a[ i] ) ;
build ( 1 , 1 , n) ;
while ( q-- )
{
int opt, x, y, z;
scanf ( "%lld" , & opt) ;
if ( opt== 1 )
{
scanf ( "%lld%lld%lld" , & x, & y, & z) ;
change ( 1 , 1 , n, x, y, z) ;
}
if ( opt== 2 )
{
scanf ( "%lld%lld%lld" , & x, & y, & z) ;
if ( y- x+ 1 < z) puts ( "NO" ) ;
else if ( y- x+ 1 == z) puts ( "YES" ) ;
else if ( query ( 1 , 1 , n, x, y- z) == query ( 1 , 1 , n, x+ z, y) ) puts ( "YES" ) ;
else puts ( "NO" ) ;
}
}
return 0 ;
}