题目链接:http://fastvj.rainng.com/problem/246827/origin
题目大意:
给你一个长度为n的字符串,m次修改,q次询问;

2 L R 1:
询问[L, R]是否为周期为1的字符串
1 L R x:
把[L, R]的字符修改为x

周期:一个串s以d为周期长度指的是d<=|s|且对任意1<=i<=|s|-d有s[i]=s[i+d]
所以:(n%d)可以不等于0

思路:根据上一篇博客的知识:https://blog.csdn.net/qq_21433411/article/details/90719116 我们已经可以维护这个字符串了。
就是如何判断周期:


我们把区间[L, R]错一下位:就会发现[L+d, R]和[L, R-d]是否相等?就能判断[L, R]为周期。

坑点:ull自然溢出会WA75.卡了我一整天。

#include <bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int maxn=100005;
ull base1 =233;
ull base2 =123;
const int mod=998244353;
ull p[2][maxn];
ull sum[2][maxn*4];
ull sf[2][maxn];

void getp()
{
    p[0][0]=1;
    p[1][0]=1;
    for(int i=1;i<maxn;i++)
    {
        p[0][i]=p[0][i-1]*base1;
        p[1][i]=p[1][i-1]*base2%mod;
    }
    sf[0][0]=sf[1][0]=1;
    for(int i=1;i<maxn;i++)
    {
        sf[0][i]=sf[0][i-1]+p[0][i];
        sf[1][i]=(sf[1][i-1]+p[1][i])%mod;
    }
}

struct Node
{
    int l ,r;

}node[maxn*4];
int add[maxn*4];

void updata(int i)
{
    sum[0][i]=sum[0][i<<1]+sum[0][(i<<1)+1]*p[0][(node[i<<1].r-node[i<<1].l+1)];
    sum[1][i]=(sum[1][i<<1]+sum[1][(i<<1)+1]*p[1][(node[i<<1].r-node[i<<1].l+1)]%mod)%mod;
    return;
}

void BT(int i, int l, int r)
{
    node[i].l=l, node[i].r=r;
    add[i]=-1;
    sum[0][i]=0;
    sum[1][i]=0;
    if(l==r)
    {
        scanf("%1d",&sum[0][i]);
        sum[1][i]=sum[0][i];
        return;
    }
    BT((i<<1), l, (l+r)/2);
    BT((i<<1)+1, (l+r)/2+1, r);
    updata(i);
    return;
}

void updown(int i)
{
    if(add[i]!=-1)
    {
        add[i<<1]=add[i];
        add[(i<<1)+1]=add[i];
        sum[0][i<<1]=add[i]*sf[0][node[i<<1].r-node[i<<1].l];
        sum[1][i<<1]=add[i]*sf[1][node[i<<1].r-node[i<<1].l]%mod;

        sum[0][(i<<1)+1]=add[i]*sf[0][node[(i<<1)+1].r-node[(i<<1)+1].l];
        sum[1][(i<<1)+1]=add[i]*sf[1][node[(i<<1)+1].r-node[(i<<1)+1].l]%mod;
        add[i]=-1;
    }
}

void up(int i, int l, int r, int c)
{
    if(node[i].l==l&&node[i].r==r)
    {
        add[i]=c;

        sum[0][i]=add[i]*sf[0][r-l];
        sum[1][i]=add[i]*sf[1][r-l]%mod;
        return;
    }
    updown(i);
    int mid=(node[i].l+node[i].r)/2;
    if(r<=mid)
    {
        up(i<<1, l, r, c);
    }
    else if(l>mid)
    {
        up((i<<1)+1, l, r, c);
    }
    else
    {
        up(i<<1, l, mid, c);
        up((i<<1)+1, mid+1, r, c);
    }
    updata(i);
    return;
}

ull ans1=0;
ull ans2=0;
void fd(int i, int l, int r, int k)
{
    if(node[i].l==l&&node[i].r==r)
    {

        ans1+=sum[0][i]*(p[0][l-k]);
        ans2=(ans2+sum[1][i]*(p[1][l-k]))%mod;

        return;
    }
    updown(i);

    int mid=(node[i].l+node[i].r)/2;
    if(r<=mid)
    {
        fd(i<<1, l, r, k);
    }
    else if(l>mid)
    {
        fd((i<<1)+1, l, r, k);
    }
    else
    {
        fd(i<<1, l, mid, k);
        fd((i<<1)+1, mid+1, r, k);
    }
    updata(i);

    return;
}

int main()
{
    getp();
    int n, q, m;
    scanf("%d%d%d",&n,&q,&m);
    q+=m;
    BT(1, 1, n);
    while(q--)
    {
        int op, L, R, d;
        scanf("%d%d%d%d",&op,&L,&R,&d);
        if(op==1)
        {
            up(1, L, R, d);
        }
        else
        {
            if(R-L+1<=d)
            {
                printf("YES\n");
                continue;
            }

            ull k1, k2, k3, k4;

            ans1=ans2=0;
            fd(1, L, R-d, L);
            k1=ans1, k2=ans2;

            ans1=ans2=0;
            fd(1, L+d, R, L+d);
            k3=ans1, k4=ans2;

            if(k1==k3&&k2==k4)
            {
                printf("YES\n");
            }
            else
            {
                printf("NO\n");
            }
        }
    }

    return 0;
}