题目大意:给你一个由0-9组成的字符串,有m个询问,两种操作,第一种将l到r的字符全部变成c,第二种问l到r这段
字符串的循环节是不是d。
思路:首先我们要知道怎么判断字符串的循环节的长度是不是d,如果这个字符串小于等于d,那么肯定是的,否则,如果l 到 r-d
和l+d 到 r 这两段字符串则循环节的长度是d,反之不是。 然后我们就用线段树维护区间字符串哈希值就好啦。
#include<bits/stdc++.h> #define read(x) scanf("%d",&x) #define lread(x) scanf("%lld",&x) #define pii pair<int,int> #define fi first #define se second #define pb push_back #define mk make_pair using namespace std; typedef long long ll; const int N=1e5+7; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3f; const int mod=1998030377; const int base=10; int n,m,k; ll b[N],sum[N]; struct seg_tree { struct node { ll hs; int l,r,lazy; }a[N<<2]; void up(int l,int r,int rt) { int mid=(l+r)>>1; int len=r-mid; a[rt].hs=(a[rt<<1].hs*b[len]+a[rt<<1|1].hs)%mod; } void down(int l,int r,int rt) { if(a[rt].lazy==-1) return; int c=a[rt].lazy; a[rt].lazy=-1; a[rt<<1].lazy=a[rt<<1|1].lazy=c; int mid=(l+r)>>1; a[rt<<1].hs=c*sum[mid-l]%mod; a[rt<<1|1].hs=c*sum[r-mid-1]%mod; } void build(int l,int r,int rt) { a[rt].l=l; a[rt].r=r; a[rt].lazy=-1; if(l==r) { int x; scanf("%1d",&x); a[rt].hs=x; return; } int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); up(l,r,rt); } void updata(int L,int R,int c,int rt) { int l=a[rt].l,r=a[rt].r; if(l>=L && r<=R) { a[rt].lazy=c; a[rt].hs=c*(sum[r-l])%mod; return; } down(l,r,rt); int mid=(l+r)>>1; if(L<=mid) updata(L,R,c,rt<<1); if(R>mid) updata(L,R,c,rt<<1|1); up(l,r,rt); } ll query(int L,int R,int rt) { int l=a[rt].l,r=a[rt].r; if(l>=L && r<=R) return a[rt].hs; down(l,r,rt); int mid=(l+r)>>1; ll ans=0; int len=max(0,min(R,r)-mid); if(R>mid) ans=query(L,R,rt<<1|1); if(L<=mid) ans=(ans+query(L,R,rt<<1)*b[len])%mod; return ans; } }seg; bool check(int l,int r,int d) { if(r-l+1<=d) return true; ll hs1=seg.query(l,r-d,1); ll hs2=seg.query(l+d,r,1); return hs1==hs2; } void init() { b[0]=1; sum[0]=1; for(int i=1;i<N;i++) b[i]=b[i-1]*base%mod; for(int i=1;i<N;i++) sum[i]=(sum[i-1]+b[i])%mod; } int main() { init(); read(n); read(m); read(k); seg.build(1,n,1); for(int i=1;i<=m+k;i++) { int op,l,r; read(op); read(l); read(r); if(op==1) { int c; read(c); seg.updata(l,r,c,1); } else { int d; read(d); if(check(l,r,d)) puts("YES"); else puts("NO"); } } return 0; }