zoukankan      html  css  js  c++  java
  • E. Kefa and Watch 题解(线段树维护hash+循环节结论)

    题目链接

    题目大意

    对数组又2种操作

    1、区间整体赋值

    2、询问[l,r]是否有长度为d的循环节

    题目思路

    其实就是一个结论

    如果s[l,r-d]==s[l+d,r],那么就有长度为d的循环节,自己画图演示即可发现

    然后线段树维护hash即可

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    #define fi first
    #define se second
    #define debug printf("aaaaaaaaaaa\n");
    const int maxn=1e5+5,inf=0x3f3f3f3f,mod=1e9+7;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    int n,m,k;
    char s[maxn];
    ull tree[maxn<<2],lazy[maxn<<2];
    ull pre[maxn],base=233,prepre[maxn];
    void updown(int node,int l,int r){
        if(lazy[node]){
            int mid=(l+r)/2;
            lazy[node<<1]=lazy[node];
            lazy[node<<1|1]=lazy[node];
            tree[node<<1]=prepre[(mid-l+1)-1]*lazy[node]%mod;
            tree[node<<1|1]=prepre[(r-mid)-1]*lazy[node]%mod;
            lazy[node]=0;
        }
    }
    
    void pushup(int node,int l,int r){
        int mid=(l+r)/2;
        // [mid+1,r]
        tree[node]=(tree[node<<1]*pre[r-mid]+tree[node<<1|1])%mod;
    }
    void build(int node,int l,int r){
        if(l==r){
            tree[node]=s[l]-'0'+1;
            return ;
        }
        int mid=(l+r)/2;
        build(node<<1,l,mid);
        build(node<<1|1,mid+1,r);
        pushup(node,l,r);
    }
    void update(int node,int L,int R,int val,int l,int r){
        if(L<=l&&r<=R){
            tree[node]=prepre[(r-l+1)-1]*val;
            lazy[node]=val;
            return ;
        }
        updown(node,l,r);
        int mid=(l+r)/2;
        if(mid>=L) update(node<<1,L,R,val,l,mid);
        if(mid<R) update(node<<1|1,L,R,val,mid+1,r);
        pushup(node,l,r);
    }
    ull query(int node,int L,int R,int l,int r){
        if(R<L) return 0;
        if(L<=l&&r<=R){
            return tree[node];
        }
        updown(node,l,r);
        int mid=(l+r)/2;
        ull ans=0;
        if(mid>=L) ans+= pre[max(0,min(R , r)- mid)]*query(node<<1,L,R,l,mid);
        if(mid<R) ans+=query(node<<1|1,L,R,mid+1,r);
        return ans%mod;
    }
    int main(){
        cin>>n>>m>>k;
        cin>>s+1;
        pre[0]=1;
        prepre[0]=1;
        for(int i=1;i<=n;i++){
            pre[i]=pre[i-1]*base%mod;
            prepre[i]=(prepre[i-1]+pre[i])%mod;
        }
        build(1,1,n);
        m+=k;
        for(int i=1,opt,l,r,c;i<=m;i++){
            cin>>opt>>l>>r>>c;
            if(opt==1){
                update(1,l,r,c+1,1,n);
            }else{
    
                ull temp1=query(1,l,r-c,1,n);
                ull temp2=query(1,l+c,r,1,n);
                if(temp1==temp2){
                    cout<<"YES\n";
                }else{
                    cout<<"NO\n";
                }
            }
        }
        return 0;
    }
    
    
    不摆烂了,写题
  • 相关阅读:
    一个棒棒糖引发的。。。
    做完了一个程序
    C# 串口操作系列(2) 入门篇,为什么我的串口程序在关闭串口时候会死锁 ? .
    MSSQL操作类
    煤矿粉尘监控系统需求分析
    C# 串口操作系列(3) 协议篇,二进制协议数据解析 .
    wp7 手机归属地查询
    .NET设计模式系列文章
    C# 串口操作系列(1) 入门篇,一个标准的,简陋的串口例子。
    常用经典算法
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/15029036.html
Copyright © 2011-2022 走看看