我们发现需要动态维护一个字符串是否成周期
根据border的一个简单性质,得出周期串的充分必要条件是,如果a[i..k]=a[j-k+1..j] 那么a[i..j]是以k为周期的串
于是可以用线段树来维护哈希
莫名其妙rank1..
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 100010
#define LL long long
#define mid (l+r>>1)
#define ls x<<1
#define rs x<<1|1
using namespace std;
int n,m,k,s[N<<2]; char c[N];
LL bas[N],p[10][N],w[N<<2];
inline void ps(int l,int r,int x){
w[x]=w[ls]*bas[r-l+1>>1]+w[rs];
}
inline void pd(int x,int m){
if(s[x]){
s[ls]=s[rs]=s[x];
w[ls]=p[s[x]-'0'][m+1>>1];
w[rs]=p[s[x]-'0'][m>>1];
s[x]=0;
}
}
inline void build(int l,int r,int x){
if(l==r){ w[x]=c[l]-'0'; return; }
build(l,mid,ls);
build(mid+1,r,rs);
ps(l,r,x);
}
inline void update(int l,int r,int x,int L,int R,int k){
if(L<=l && r<=R){ w[x]=p[k-'0'][r-l+1]; s[x]=k; return; }
pd(x,r-l+1);
if(L<=mid) update(l,mid,ls,L,R,k);
if(mid<R) update(mid+1,r,rs,L,R,k);
ps(l,r,x);
}
inline LL gH(int l,int r,int x,int L,int R){
if(L<=l && r<=R) return w[x];
pd(x,r-l+1); LL S=0;
if(L<=mid) S=gH(l,mid,ls,L,R);
if(mid<R) S=S*bas[min(r,R)-mid]+gH(mid+1,r,rs,L,R);
return S;
}
int main(){
scanf("%d%d%d%s",&n,&m,&k,c+1); m+=k;
for(int i=*bas=1;i<=n;++i){
bas[i]=bas[i-1]*13;
for(int j=0;j<10;++j)
p[j][i]=p[j][i-1]*13+j;
}
build(1,n,1);
for(int o,l,r,c;m--;){
scanf("%d%d%d%d",&o,&l,&r,&c);
if(o==1) update(1,n,1,l,r,c+'0');
else {
if(c==r-l+1) puts("YES");
else if(gH(1,n,1,l,r-c)==gH(1,n,1,l+c,r)) puts("YES"); else puts("NO");
}
}
}