这道题的做法有很多。
先讲一种最好理解的算法:O(n^2)暴力修改、O(n^2)暴力询问,期望得分30,实际得分100。。。
一看就是不负责任的XX哥gen的数据。——Scarlet
ljg告诉我,这题只用写300B,然而我满脑子线段树,还是选择了自己的SB算法。
然后第二种,线段树+哈希,nlogn直接过。
第三种,某蒟蒻并没有想到直接判query(l,r-c)==query(l+c,r),然后就用了倍增处理,然后就挂了QAQ。
“这是我见过最傻逼的人。”wamach对镜子说。
奇丑无比的代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define rep(i,j,k) for(i=j;i<=k;i++)
#define per(i,j,k) for(i=j;i>=k;i--)
const int N=100005;
int n,m,k,T[N<<2],lz[N<<2],bin[N],Sb[N];char s[N];
void pd(int l,int r,int num){
if(!lz[num])return;
if(l==r)T[num]=lz[num];
else{
lz[num<<1]=lz[num<<1|1]=lz[num];
T[num]=Sb[r-l]*lz[num];
}
lz[num]=0;
}
void up(int l,int mid,int r,int num){
pd(l,mid,num<<1);pd(mid+1,r,num<<1|1);
T[num]=T[num<<1]*bin[r-mid]+T[num<<1|1];
}
void build(int l,int r,int num){
if(l==r){
T[num]=s[l]-'/';return;
}
int mid=l+r>>1;
build(l,mid,num<<1);
build(mid+1,r,num<<1|1);
up(l,mid,r,num);
}
void modify(int x,int L,int R,int l,int r,int num){
int mid=l+r>>1;
if(L<=l&&r<=R){
lz[num]=x+1;pd(l,r,num);return;
}
pd(l,r,num);
if(L<=mid)modify(x,L,R,l,mid,num<<1);
if(R>mid)modify(x,L,R,mid+1,r,num<<1|1);
up(l,mid,r,num);
}
int query(int L,int R,int l,int r,int num){
int mid=l+r>>1;pd(l,r,num);
if(L<=l&&r<=R)return T[num];
int rtn=0;
if(R<=mid)return query(L,R,l,mid,num<<1);
if(L>mid)return query(L,R,mid+1,r,num<<1|1);
return query(L,mid,l,mid,num<<1)*bin[R-mid]+query(L,R,mid+1,r,num<<1|1);
}
int main(){
// freopen("w.out","w",stdout);
int i,o,x,y,yy,z,tmp[20],ln,u,v;
scanf("%d%d%d%s",&n,&m,&k,s+1);
bin[0]=Sb[0]=1;
rep(i,1,n){
bin[i]=bin[i-1]*11;Sb[i]=Sb[i-1]+bin[i];
}
build(1,n,1);
for(m+=k;m--;){
scanf("%d%d%d%d",&o,&x,&y,&z);
if(o==1)modify(z,x,y,1,n,1);
else{
if(!z){puts("YES");continue;}
yy=y;y-=(y-x+1)%z;
tmp[ln=1]=query(u=x,v=x+z-1,1,n,1);
for(z<<=1;(v=x+z-1)<=y;z<<=1){
tmp[++ln]=query(u,v,1,n,1);
if(tmp[ln]!=tmp[ln-1]*(bin[z>>1]+1))break;
}
if(v<=y){puts("NO");continue;}
u+=z>>1;
for(z>>=2;u<=y;u=v+1,z>>=1){
for(--ln;(v=u+z-1)>y;)z>>=1,--ln;
if(tmp[ln]!=query(u,v,1,n,1))break;
}
if(u<=y){puts("NO");continue;}
puts(yy==y||query(y+1,yy,1,n,1)==query(x,x+yy-y-1,1,n,1)?"YES":"NO");
}
}
return 0;
}