zoukankan      html  css  js  c++  java
  • Codeforces Round #321 (Div. 2)-E(线段树+hash

    题目:给出一个序列,有两种询问,一种是把某个区间的数全部变为一个数,一种是查询一个区间是否为以d为周期.

    思路:线段树维护区间的hash值,然后对于一个区间[l,r]如果[l,r-d]和[l+d,r]相等那么这个区间的周期就是d.

    注意cf上的自然溢出hash几乎必然被hack....hack方法见此文:http://codeforces.com/blog/entry/4898

    /*
    * @author:  Cwind
    */
    #include <bits/stdc++.h>
    #define pb push_back
    #define PB pop_back
    #define bk back()
    #define se second
    #define fs first
    #define IINF (1<<29)
    #define sq(x) (x)*(x)
    #define eps 0.000000001
    #define clr(x) memset((x),0,sizeof (x))
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<ll,ll> P;
    const int maxn=1e5+399;
    ull H=2347;
    ull H2=1007;
    const ull mod=1e9+7;
    ull hashsum[maxn];
    ull hashpow[maxn];
    int a[maxn];
    int n,m,k;
    const int maxp=1e6;
    struct Node{
        int l,r;
        ull hash;
        int val,s;
        Node *ch[2];
        bool lazy;
        void pushdown(){
            if(r-l<=1) return;
            if(lazy){
                lazy=0;
                ch[0]->lazy=ch[1]->lazy=1;
                ch[0]->val=ch[1]->val=val;
                ch[0]->hash=val*hashsum[ch[0]->s-1]%mod;
                ch[1]->hash=val*hashsum[ch[1]->s-1]%mod;
            }
        }
    }pool[maxp];
    int ph=0;
    Node *newNode(){
        Node *n=&pool[ph++];
        n->lazy=0;
        return n;
    }
    void build(Node *n,int l,int r){
        n->l=l,n->r=r;
        if(r-l<=1){
            n->hash=a[l];
            n->s=1;
            return;
        }
        n->ch[0]=newNode();
        n->ch[1]=newNode();
        Node *chl=n->ch[0],*chr=n->ch[1];
        build(chl,l,(l+r)/2);
        build(chr,(l+r)/2,r);
        n->s=chr->s+chl->s;
        n->hash=(chl->hash+chr->hash*hashpow[chl->s]%mod)%mod;
    }
    void update(Node *n,int a,int b,int v){
        n->pushdown();
        int l=n->l,r=n->r;
        if(l>=b||a>=r) return;
        if(a<=l&&b>=r){
            n->lazy=1;
            n->val=v;
            n->hash=v*hashsum[n->s-1]%mod;
            return;
        }
        Node *chl=n->ch[0],*chr=n->ch[1];
        update(chl,a,b,v);
        update(chr,a,b,v);
        n->hash=(chl->hash+chr->hash*hashpow[chl->s]%mod)%mod;
    }
    ull getHash(Node *n,int a,int b){
        n->pushdown();
        int l=n->l,r=n->r;
        if(l>=b||a>=r) return 0;
        if(l>=a&&r<=b) return n->hash;
        int ll=max(a,l),rr=min(b,r);
        int mid=n->ch[1]->l;
        if(mid>ll){
            return (getHash(n->ch[0],a,b)+getHash(n->ch[1],a,b)*hashpow[mid-ll])%mod;
        }else 
            return getHash(n->ch[1],a,b)%mod;
    }
    void init(){
        hashsum[0]=1;
        hashpow[0]=1;
        for(int i=1;i<maxn;i++){
            hashsum[i]=(hashsum[i-1]*H+1)%mod;
            hashpow[i]=(hashpow[i-1]*H)%mod;
        }
    }
    Node *root;
    char r[maxn];
    int main(){
        ///freopen("/home/files/CppFiles/in","r",stdin);
        //freopen("defense.in","r",stdin);
        //freopen("defense.out","w",stdout);
        init();
        root=newNode();
        cin>>n>>m>>k;
        scanf("%s",r);
        for(int i=1;i<=n;i++){
            a[i]=r[i-1]-'0';
        }
        build(root,1,n+1);
        for(int ttt=0;ttt<m+k;ttt++){
            int o,x,y,z;
            scanf("%d%d%d%d",&o,&x,&y,&z);
            if(o==1){
                update(root,x,y+1,z);
            }else{
                ull hash1=getHash(root,x,y-z+1);
                ull hash2=getHash(root,x+z,y+1);
                if(hash1==hash2){
                    puts("YES");
                }else{
                    puts("NO");
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    luogu P1073 最优贸易 |分层图最短路
    luogu P1901 发射站 |单调队列
    luogu P1759 通天之潜水 |背包
    luogu P1801 【黑匣子_NOI导刊2010提高(06)】|堆+分块
    bzoj1642[Usaco2007 Nov]Milking Time 挤奶时间*
    bzoj1616[Usaco2008 Mar]Cow Travelling游荡的奶牛*
    bzoj1623[Usaco2008 Open]Cow Cars 奶牛飞车*
    bzoj1612[Usaco2008 Jan]Cow Contest奶牛的比赛*
    bzoj1639[Usaco2007 Mar]Monthly Expense 月度开支*
    bzoj1601[Usaco2008 Oct]灌水*
  • 原文地址:https://www.cnblogs.com/Cw-trip/p/4833524.html
Copyright © 2011-2022 走看看