51Nod1553 周期串查询

题目看这里

我们发现需要动态维护一个字符串是否成周期

根据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");
        }
    }
}

posted @ 2018-03-22 22:06  扩展的灰(Extended_Ash)  阅读(177)  评论(0编辑  收藏  举报