zoukankan      html  css  js  c++  java
  • luogu P5324 [BJOI2019]删数

    传送门

    不如先考虑暴力,能删的序列首先有(1,2,3...n),还有就是升序排序后从后往前放数,第(i)位要么放(i),要么放(i+1)位置的数,例如(1,2,4,4,5,6,9,9,9)

    如果一个数(i)出现了若干次,假如是(num_i)次,我们发现是可以在(i,i-1,i-2...i-num_i+1)上放(i)的,这样放完之后,如果有的位置没有用到现有的数放上去,那么就要从没用的数里改一个放过来,问题也就是用一堆数,最多能放多少个位置.考虑从后往前放,然后如果一个位置有多个数就接着用这种数往后放.如果放到一个位置(j),(j)有若干个,当前的(i)也有若干个,我们只能用一种放,那么显然要用更多的那种放.最后没放数的位置数就是答案.

    为了方便,我们把放数看成区间覆盖,即一个(i)可以覆盖([i-num_i+1,i])这段区间,我们再给所有覆盖区间加上(1),那就是求([1,n])(0)的个数.注意到修改的(+1/-1)都是整体的,所以如果把所有数放在一根数轴上,那么初始要统计的区间为([1,n]),然后整体(+1)相当于统计区间整体向左移(1),然后 以原统计区间右端点 为右端点 的对应区间覆盖的贡献要减掉,因为那个右端点的数超过统计范围,不能放进来;整体(-1)相当于统计区间整体向右移(1),然后 以原统计区间右端点 为右端点 的对应区间覆盖的贡献要加上;单点修改,也就是原来的(num_{a_p})(1),后面的新的(num)(1),这导致对应两个覆盖区间左端点右移和左移.这些东西可以用线段树维护,注意线段树的叶子数量应该是(n+q+q)

    至于区间(0)的数量,用值域线段树维护因为区间(+1),某个位置最少为(0),只要维护区间最小值及数量就行了

    // luogu-judger-enable-o2
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<map>
    #include<set>
    #define LL long long
    #define db double
    
    using namespace std;
    const int N=150000+10,M=N*3;
    int rd()
    {
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    struct node
    {
        int mi,nm;
        node(){mi=0,nm=1;}
        node(int nmi,int nnm){mi=nmi,nm=nnm;}
        node operator + (const node &bb) const
        {
            if(mi==bb.mi) return node(mi,nm+bb.nm);
            return mi<bb.mi?(*this):bb;
       	}
        void ad(int x){mi+=x;}
    }s[M<<2],nw;
    int tg[M<<2];
    void psup(int o){s[o]=s[o<<1]+s[o<<1|1];}
    void psdn(int o){if(tg[o]) s[o<<1].ad(tg[o]),tg[o<<1]+=tg[o],s[o<<1|1].ad(tg[o]),tg[o<<1|1]+=tg[o],tg[o]=0;}
    #define mid ((l+r)>>1)
    int nl,nr;
    void modif(int o,int l,int r,int ll,int rr,int x)
    {
        if(ll<=l&&r<=rr){s[o].ad(x),tg[o]+=x;return;}
        psdn(o);
        if(ll<=mid) modif(o<<1,l,mid,ll,rr,x);
        if(rr>mid) modif(o<<1|1,mid+1,r,ll,rr,x);
        psup(o);
    }
    void modif(int lx,int x)
    {
        int o=1,l=nl,r=nr,st[21],tp=0;
        while(l<r)
        {
            st[++tp]=o,psdn(o);
            if(lx<=mid) o=o<<1,r=mid;
            else o=o<<1|1,l=mid+1;
        }
        s[o].ad(x);
        while(tp)
        {
            o=st[tp--];
            psup(o);
        }
    }
    node quer(int o,int l,int r,int ll,int rr)
    {
        if(ll<=l&&r<=rr) return s[o];
        psdn(o);
        node an;
        an.mi=M;
        if(ll<=mid) an=an+quer(o<<1,l,mid,ll,rr);
        if(rr>mid) an=an+quer(o<<1|1,mid+1,r,ll,rr);
        psup(o);
        return an;
    }
    void bui(int o,int l,int r)
    {
        if(l==r) return;
        bui(o<<1,l,mid),bui(o<<1|1,mid+1,r);
        psup(o);
    }
    int n,q,a[N],nm[M],ll=150001,rr;
    
    
    int main()
    {
        n=rd(),q=rd();
        rr=ll+n-1;
        nl=ll-q,nr=rr+q;
        bui(1,nl,nr);
        for(int i=1;i<=n;++i)
        {
            a[i]=rd()+ll-1;
            ++nm[a[i]];
            modif(a[i]-nm[a[i]]+1,1);
        }
        while(q--)
        {
            int p=rd();
            if(!p)
            {
                if(~rd())
                {
                    if(nm[rr]) modif(1,nl,nr,rr-nm[rr]+1,rr,-1);
                    --ll,--rr;
                }
                else
                {
                    ++ll,++rr;
                    if(nm[rr]) modif(1,nl,nr,rr-nm[rr]+1,rr,1);
                }
            }
            else
            {
                if(a[p]<=rr) modif(a[p]-nm[a[p]]+1,-1);
                --nm[a[p]];
                a[p]=rd()+ll-1;
                ++nm[a[p]];
                modif(a[p]-nm[a[p]]+1,1);
            }
            nw=quer(1,nl,nr,ll,rr);
            printf("%d
    ",nw.mi?0:nw.nm);
        }
        return 0;
    }
    
  • 相关阅读:
    python中常用的模块二
    python中常用的模块一
    python类与类的关系
    python类的成员
    关于python的面向对象
    python内置函数2
    python内置函数
    python fileinput模块
    python生成器
    python 迭代器
  • 原文地址:https://www.cnblogs.com/smyjr/p/10770696.html
Copyright © 2011-2022 走看看