码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #321 (Div. 2) E - Kefa and Watch

时间:2018-02-18 23:39:47      阅读:319      评论:0      收藏:0      [点我收藏+]

标签:using   bsp   ase   query   color   its   check   long   names   

题目大意:给你一个由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;
}

 

Codeforces Round #321 (Div. 2) E - Kefa and Watch

标签:using   bsp   ase   query   color   its   check   long   names   

原文地址:https://www.cnblogs.com/CJLHY/p/8453344.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!