zoukankan      html  css  js  c++  java
  • gym102798 Caesar Cipher (2020 China Collegiate Programming Contest, Weihai Site) 线段树

    题意

    有一个一个长度为n的数组a和两种操作(1代表对区间([l,r])加1,2代表询问区间([x,x+L-1])和区间([y,y+L-1])是否相同),其中操作1对65536取模。

    思路

    容易想到可以用哈希判断是否相等。然后题目中的数组是对65536取模的,就会想到hash的模数取65536,即用unsigned short自然溢出取模,但是这个模数被出题人卡掉了。

    另外,做字符串哈希时,哈希的模数一般会选用大指数。因为当base和mod互质时,这个hash函数在([0,mod))上每个值概率相等,此时单次比较的错误率为(frac1{mod})

    对于65536取模的情况,与codeforces438D相同,除了区间和外再加一个区间最大值,对于大于等于65536的区间暴力修改。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    const ll base=1e8+7;
    const int maxn=5e5+5;
    
    struct Tree{
        ll max,sum,tag;
    }tree[maxn*4];
    ll a[maxn],p[maxn],pre[maxn];
    int n,q;
    
    
    ll M(ll val){
        return val>=mod?val-mod:val<0?val+mod:val;
    }
    
    void push_up(int i)
    {
        tree[i].max=max(tree[i<<1].max,tree[i<<1|1].max);
        tree[i].sum=M(tree[i<<1].sum+tree[i<<1|1].sum);
    }
    
    void push_down(int i,int L,int R)
    {
        if(tree[i].tag)
        {
            tree[i<<1].max+=tree[i].tag;
            tree[i<<1|1].max+=tree[i].tag;
            int mid=L+R>>1;
            if(L!=mid)
                tree[i<<1].tag+=tree[i].tag;
            if(mid+1!=R)
                tree[i<<1|1].tag+=tree[i].tag;
            tree[i<<1].sum=M(tree[i<<1].sum+M(pre[mid]-pre[L-1])*tree[i].tag%mod);
            tree[i<<1|1].sum=M(tree[i<<1|1].sum+M(pre[R]-pre[mid])*tree[i].tag%mod);
            tree[i].tag=0;
        }
    }
    
    void build(int i,int l,int r)
    {
        if(l==r)
        {
            tree[i].max=a[l];
            tree[i].sum=a[l]*p[l]%mod;
            tree[i].tag=0;
            return;
        }
        int mid=l+r>>1;
        build(i<<1,l,mid);
        build(i<<1|1,mid+1,r);
        push_up(i);
    }
    
    void add(int i,int l,int r,int L,int R)
    {
        push_down(i,L,R);
        if(l==L && r==R)
        {
            if(l==r)
            {
                tree[i].max++;
                if(tree[i].max==65536)tree[i].max=0;
                tree[i].sum=tree[i].max*p[l]%mod;
                return;
            }
            else if(tree[i].max<65535)
            {            
                tree[i].max++;
                tree[i].tag++;
                tree[i].sum=M(tree[i].sum+M(pre[R]-pre[L-1]));
                return;
            }
        }
        int mid=L+R>>1;
        if(r<=mid)
            add(i<<1,l,r,L,mid);
        else if(l>mid)
            add(i<<1|1,l,r,mid+1,R);
        else
        {
            add(i<<1,l,mid,L,mid);
            add(i<<1|1,mid+1,r,mid+1,R);
        }
        push_up(i);
    }
    
    ll cal(int i,int l,int r,int L,int R)
    {
        push_down(i,L,R);
        int mid=L+R>>1;
        if(l==L && r==R)return tree[i].sum;
        if(r<=mid)
            return cal(i<<1,l,r,L,mid);
        else if(l>mid)
            return cal(i<<1|1,l,r,mid+1,R);
        else
            return M(cal(i<<1,l,mid,L,mid)+cal(i<<1|1,mid+1,r,mid+1,R));
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
    
        cin>>n>>q;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        p[0]=1;
        pre[0]=1;
        for(int i=1;i<=n;i++)
        {
            p[i]=p[i-1]*base%mod;
            pre[i]=M(pre[i-1]+p[i]);
        }
    
        build(1,1,n);
        int op,l,r,x,y,L;
        while(q--)
        {
            cin>>op;
            if(op==1)
            {
                cin>>l>>r;
                add(1,l,r,1,n);
            }
            else
            {
                cin>>x>>y>>L;
                if(x>y)swap(x,y);
                ll res1=cal(1,x,x+L-1,1,n),res2=cal(1,y,y+L-1,1,n);
                if(res1*p[y-x]%mod==res2)
                    cout<<"yes
    ";
                else
                    cout<<"no
    ";
            }
            
        }
    
        return 0;
    }
    
  • 相关阅读:
    2021.1.28 个人rating赛补题报告
    2021.1.23 个人rating赛补题报告
    2021.1.23 个人rating赛补题报告
    2020.12.14 个人训练赛补题报告
    2020.11.28 2020团体程序设计天梯赛补题报告
    2020.12.3 Codeforces Beta Round #73(Div2)补题报告
    Xhorse VVDI Prog V5.0.6 is Ready for BCM2 Adapter
    Program 2021 Ford Bronco All Keys Lost using VVDI Key Tool Plus
    Xhorse VVDI Prog V5.0.4 Software Update in July 2021
    How to use Xhorse VVDI2 to Exchange BMW FEM/BDC Module?
  • 原文地址:https://www.cnblogs.com/intmian/p/14015085.html
Copyright © 2011-2022 走看看