CF #321 (Div. 2) E
用线段树维护哈希,类似于进位制的一个哈希 a[i]*p^i+a[i-1]*p^i-1...
然后,线段树存在某区间的哈希的值,对于更新,则只需提前计算出整段的哈希值即可。
判断是否相等,由于相隔为d,只需计算(l+d,r),(l,r-d)两段哈希的值是否相等即可。为了防止一次哈希可能使不符合条件的值哈希值相等,所以进行了两次哈希。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define LL long long
using namespace std;
const int MAX=100010;
const LL m1=1000000007;
const LL m2=1000000009;
const int g1=47;
const int g2=67;
char str[MAX];
struct HASH{
LL seg[MAX<<2]; int lazy[MAX<<2];
LL bits[10][MAX]; LL mod,gt; LL ebit[MAX];
void init(LL m,LL g){
mod=m; gt=g;
for(int i=0;i<MAX;i++){
if(i==0) ebit[i]=1;
else {
ebit[i]=(ebit[i-1]*gt)%mod;
}
}
for(int i=0;i<=9;i++){
bits[i][0]=0;
for(int j=1;j<MAX;j++){
bits[i][j]=(bits[i][j-1]*gt%mod+i)%mod;
}
}
}
void push_up(int rt,int l,int r){
seg[rt]=(seg[rt<<1|1]+seg[rt<<1]*ebit[r-(l+r)/2])%mod;
}
void push_down(int rt,int l,int r){
if(lazy[rt]!=-1){
int m=(l+r)>>1;
lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
seg[rt<<1]=bits[lazy[rt]][m-l+1];
seg[rt<<1|1]=bits[lazy[rt]][r-m];
lazy[rt]=-1;
}
}
void build(int rt,int l,int r){
if(l==r){
seg[rt]=(str[l]-'0')%mod;
lazy[rt]=-1;
return ;
}
int m=(l+r)>>1;
build(rt<<1,l,m);
build(rt<<1|1,m+1,r);
push_up(rt,l,r);
lazy[rt]=-1;
}
void update(int rt,int l,int r,int L,int R,int d){
if(l<=L&&R<=r){
lazy[rt]=d;
seg[rt]=bits[d][R-L+1];
return ;
}
int m=(L+R)>>1;
push_down(rt,L,R);
if(m>=l)
update(rt<<1,l,r,L,m,d);
if(m+1<=r)
update(rt<<1|1,l,r,m+1,R,d);
push_up(rt,L,R);
}
void query(int rt ,int l,int r,int L,int R,LL &res){
if(l<=L&&R<=r){
res=(res*ebit[R-L+1]+seg[rt])%mod;
return ;
}
push_down(rt,L,R);
int m=(L+R)>>1;
if(m>=l)
query(rt<<1,l,r,L,m,res);
if(m+1<=r) query(rt<<1|1,l,r,m+1,R,res);
}
bool check(int l,int r,int d,int n){
if(r-l+1==d) return true;
LL lrt=0; query(1,l,r-d,1,n,lrt);
LL rrt=0; query(1,l+d,r,1,n,rrt);
if(lrt==rrt) return true;
return false;
}
}a,b;
int main(){
// cout<<"OK"<<endl;
int n,m,k,op,l,r,d;
// cout<<"OK"<<endl;
// HASH a,b;
/// cout<<"OK"<<endl;
while(scanf("%d%d%d",&n,&m,&k)!=EOF){
scanf("%s",str+1);
a.init(m1,g1);
b.init(m2,g2);
a.build(1,1,n);
b.build(1,1,n);
/// cout<<"YES"<<endl;
m+=k;
while(m--){
scanf("%d%d%d%d",&op,&l,&r,&d);
if(op==1){
a.update(1,l,r,1,n,d);
b.update(1,l,r,1,n,d);
}
else{
if(a.check(l,r,d,n)&&b.check(l,r,d,n)){
puts("YES");
}
else puts("NO") ;
}
}
}
return 0;
}

浙公网安备 33010602011771号