• Luogu P3960 列队 线段树


    题面

    线段树入门题。

    我们考虑线段树来维护这个矩阵。

    首先我们先定n+1棵线段树前n棵维护每行前m-1个同学中没有离队过的同学,还有一棵维护第m列中没有离队过的同学。再定n+1棵线段树前n棵线段树维护每行因一个同学离队而从第m列插♂进来的同学,还有一棵维护到队尾的同学。

    具体怎么维护?比如当前的询问是(x,y),先分两种情况:

    1.不在第m列。

    那么我们就先看看这个同学是不是插♂进来,是的话就在那后n+1棵线段树的第x棵里找,不然就在前n+1棵的第x棵里找。

    然后在对应线段树的对应位置里删除离队的同学,将第m列的第x行的那个同学(需要先判断是在前n+1棵里的第n+1棵还是后n+1棵)插♂到后n+1棵线段树的第x棵的最后,再把他原先所在的那个线段树里对应的位置删掉。最后把离队的同学插♂到后n+1棵线段树的第n+1棵的最后。

    2.在第m列

    先判断是在前n+1棵里的第n+1棵还是后n+1棵,然后他所在的那个线段树里对应的位置删掉,最后把离队的同学插♂到后n+1棵线段树的第n+1棵的最后。

    //by zykykyk
    #include<cstdio>
    #include<ctime>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #include<cstring>
    #define rg register
    #define il inline
    #define vd void
    #define ll long long
    #define N 300010
    #define For(i,x,y) for (rg int i=(x);i<=(y);i++)
    #define Dow(i,x,y) for (rg int i=(x);i>=(y);i--)
    #define cross(i,k) for (rg int i=first[k];i;i=last[i])
    using namespace std;
    il ll max(ll x,ll y){return x>y?x:y;}
    il ll min(ll x,ll y){return x<y?x:y;}
    il ll read(){
        ll x=0;int ch=getchar(),f=1;
        while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
        if (ch=='-'){f=-1;ch=getchar();}
        while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,q,x,y;
    
    int Tot,Rt[N],Sum[N*20],Lson[N*20],Rson[N*20],cnt[N];
    ll V[N*20];
    il vd Update(int &u,int l,int r,int ql,ll x,int k){
        if (!u) u=++Tot;Sum[u]+=k;
        if (l==r){V[u]=x;return;}
        int mid=l+r>>1;
        if (ql<=mid) Update(Lson[u],l,mid,ql,x,k);
            else Update(Rson[u],mid+1,r,ql,x,k);
    }
    il ll Query(int u,int l,int r,int k){
        if (l==r) return V[u];
        int mid=l+r>>1;
        if (Sum[Lson[u]]>=k) return Query(Lson[u],l,mid,k);
            else return Query(Rson[u],mid+1,r,k-Sum[Lson[u]]);
    }
    il int Query_id(int u,int l,int r,int k){
        //printf("l=%d r=%d Sum[Lson[u]]=%d
    ",l,r,Sum[Lson[u]]);
        if (l==r) return l;
        int mid=l+r>>1;
        if (Sum[Lson[u]]>=k) return Query_id(Lson[u],l,mid,k);
            else return Query_id(Rson[u],mid+1,r,k-Sum[Lson[u]]);
    }
    
    int tot,rt[N],v[N*20],lson[N*20],rson[N*20];
    il vd update(int &u,int l,int r,int ql,int k){
        if (!u) u=++tot;v[u]+=k;
        if (l==r) return;
        int mid=l+r>>1;
        if (ql<=mid) update(lson[u],l,mid,ql,k);
            else update(rson[u],mid+1,r,ql,k);
    }
    il ll query(int u,int l,int r,int k){
        if (l==r) return l;
        int mid=l+r>>1,V=mid-l+1-v[lson[u]];
        if (V>=k) return query(lson[u],l,mid,k);
            else return query(rson[u],mid+1,r,k-V);
    }
    
    il ll work(int x,ll y){
        ll ans;
        if (n-v[rt[n+1]]>=x){
            ll X=query(rt[n+1],1,n,x);
            ans=X*(1ll*m);
            update(rt[n+1],1,n,X,1);//printf("X=%lld
    ",X);
        }
        else {
            ans=Query(Rt[n+1],1,q,x-n+v[rt[n+1]]);//printf("%d 233
    ",Query_id(Rt[n+1],1,q,x-n+v[rt[n+1]]));
            Update(Rt[n+1],1,q,Query_id(Rt[n+1],1,q,x-n+v[rt[n+1]]),0,-1);
        }
        cnt[n+1]++;
        Update(Rt[n+1],1,q,cnt[n+1],y?y:ans,1);
        return ans;
    }
    il ll Work(int x,int y){
        ll ans;
        if (m-1-v[rt[x]]>=y){
            ll X=query(rt[x],1,m-1,y);
            ans=1ll*(x-1)*m+X;
            update(rt[x],1,m-1,X,1);
        }
        else {
            ans=Query(Rt[x],1,q,y-(m-1-v[rt[x]]));
            Update(Rt[x],1,q,Query_id(Rt[x],1,q,y-(m-1-v[rt[x]])),0,-1);
        }
        cnt[x]++;
        ll k=work(x,ans);Update(Rt[x],1,q,cnt[x],k,1);//printf("k=%lld
    ",k);
        return ans;
    }
    
    int main(){
        freopen("phalanx.in","r",stdin);
        freopen("phalanx.out","w",stdout);
        n=read(),m=read(),q=read();
        For(i,1,q){
            x=read(),y=read();
            if (y==m) printf("%lld
    ",work(x,0));
                else printf("%lld
    ",Work(x,y));
        }
    }
  • 相关阅读:
    讲课专用——线段树——最长上升子序列
    讲课专用——线段树——最长连续空位
    讲课专用——线段树——BSS
    求背景图
    致备战noip2018的勇士
    TNS-12547 Linux Error: 104: Connection reset by pe (转载)
    清理Oracle安装目录里的一些日志信息
    tmp_table_size
    11gr2 alert日志中报TNS-12535 TNS-00505原因及解决方法 (转载)
    systemstate dump 介绍
  • 原文地址:https://www.cnblogs.com/zykykyk/p/8903629.html
Copyright © 2020-2023  润新知