zoukankan      html  css  js  c++  java
  • Codeforces Round #321 (Div. 2) E

    题目大意:给你一个由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;
    }
  • 相关阅读:
    常用排序
    NetBeans 时事通讯(刊号 # 130 Dec 23, 2010)
    《让子弹飞》向我们提出的问题
    NetBeans 时事通讯(刊号 # 130 Dec 23, 2010)
    过去与今天
    过去与今天
    不搞笑不给力——年会小品《山寨新闻联播》
    GAE 博客——B3log Solo 0.2.5 Beta1 发布了!
    EverBox(同步网盘)邀请
    GAE 博客——B3log Solo 0.2.5 Beta1 发布了!
  • 原文地址:https://www.cnblogs.com/CJLHY/p/8453344.html
Copyright © 2011-2022 走看看