• BZOJ4942 & UOJ314:[NOI2017]整数——题解


    https://www.lydsy.com/JudgeOnline/problem.php?id=4942

    http://uoj.ac/problem/314

    https://www.luogu.org/problemnew/show/P3822

    题面是markdown形式的所以我传不上……

    UPD:18.5.11改成对参考代码的理解失误。

    参考:http://www.cnblogs.com/RabbitHu/p/UOJ314.html仔细思考之后发现lazy标记可以不下传,因为区间修改都是改0/INF,单点修改就直接改就行了……

    (晚上睡前突然发现这个sb问题然后太晚了只好现在改。)

    暴力修改显然是不行的。

    考虑让你改的是a*2^b,已经明示了想让你直接修改二进制位,于是把a用O(log)时间拆成二进制然后log次加减,期间的进位退位问题用参考博客的方法可以O(log)实现。

    但问题是位数一共有3e7……显然会T的。

    于是压60位,这样时间复杂度就有保证了。

    (我记得以前有人批评松松松就是因为他WC出神题然后NOI出签到题……woc我怕不是送分题都做不出来我退役吧。)

    #include<cstdio>
    #include<queue>
    #include<cctype>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=5e5+5;
    const int B=60;
    const ll INF=(1LL<<B)-1;
    inline ll read(){
        ll X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    ll lazy[N*4+100],val[N*4+100];
    int pos[N*4+100];
    bool tag[N*4+10][2];
    inline void upt(int a){
        tag[a][0]=tag[a<<1][0]&tag[a<<1|1][0];
        tag[a][1]=tag[a<<1][1]&tag[a<<1|1][1];
    }
    inline void mdy(int a,ll x){
        if(pos[a]!=-1)val[pos[a]]=x;
        if(x==0)tag[a][0]=1,tag[a][1]=0;
        else if(x==INF)tag[a][0]=0,tag[a][1]=1;
        else tag[a][0]=tag[a][1]=0;
        lazy[a]=x;
    }
    inline void push(int a){
        if(lazy[a]==-1)return;
        mdy(a<<1,lazy[a]);
        mdy(a<<1|1,lazy[a]);
        lazy[a]=-1;
    }
    void build(int a,int l,int r){
        tag[a][0]=1;lazy[a]=-1;pos[a]=-1;
        if(l==r){
            pos[a]=l;
            return;
        }
        int mid=(l+r)>>1;
        build(a<<1,l,mid);build(a<<1|1,mid+1,r);
    }
    void modify(int a,int l,int r,int l1,int r1,ll x){
        if(r<l1||r1<l||l1>r1)return;
        if(l1<=l&&r<=r1){
            mdy(a,x);
            return;
        }
        push(a);
        int mid=(l+r)>>1;
        modify(a<<1,l,mid,l1,r1,x);
        modify(a<<1|1,mid+1,r,l1,r1,x);
        upt(a);
    }
    ll query(int a,int l,int r,int p){
        if(l==r)return val[l];
        push(a);
        int mid=(l+r)>>1;
        if(p<=mid)return query(a<<1,l,mid,p);
        else return query(a<<1|1,mid+1,r,p);
    }
    int find(int a,int l,int r,int p,int o){
        if(tag[a][!o])return -1;
        if(l==r)return l;
        push(a);
        int mid=(l+r)>>1,tmp;
        if(p<=mid&&(tmp=find(a<<1,l,mid,p,o))!=-1)return tmp;
        return find(a<<1|1,mid+1,r,p,o);
    }
    void add(int p,ll x){
        ll tmp=query(1,0,N,p);
        modify(1,0,N,p,p,(tmp+x)&INF);
        if(tmp+x>INF){
            int r=find(1,0,N,p+1,0);
            modify(1,0,N,r,r,val[r]+1);
            modify(1,0,N,p+1,r-1,0);
        }
    }
    void del(int p,ll x){
        ll tmp=query(1,0,N,p);
        modify(1,0,N,p,p,(tmp-x)&INF);
        if(tmp-x<0){
            int r=find(1,0,N,p+1,1);
            modify(1,0,N,r,r,val[r]-1);
            modify(1,0,N,p+1,r-1,INF);
        }
    }
    int main(){
        int n=read();read(),read(),read();
        build(1,0,N);
        for(int i=1;i<=n;i++){
            int op=read();
            if(op==1){
                ll a=read(),b=read();
                ll p=b/B,m=b%B;
                if(a>0){
                    ll x=(ll)a<<m&INF;
                    if(x)add(p,x);
                    p++;a>>=(B-m);
                    if(a)add(p,a);
                }else{
                    a=-a;
                    ll x=(ll)a<<m&INF;
                    if(x)del(p,x);
                    p++;a>>=(B-m);
                    if(a)del(p,a);
                }
            }else{
                ll k=read();
                printf("%lld
    ",query(1,0,N,k/B)>>(k%B)&1);
            }
        }
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

    +本文作者:luyouqi233。               +

    +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/ +

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    同步锁笔记
    android 编译错误
    多线程、Handler机制、ThreadLocal
    [MySQL]MySQL8.0的一些注意事项以及解决方案
    [SuperSocket2.0]SuperSocket 2.0从入门到懵逼
    mavlink协议CRC校验
    String类字节码编译查看
    iOS获取设备名称
    URL编码和解码
    iOS编译SDK自动化脚本(.framework+.a)
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/9021723.html
Copyright © 2020-2023  润新知