zoukankan      html  css  js  c++  java
  • 题解 P3960 【列队】

    题目链接:Link

    Problem

    Solution

    考虑到每个点都是先横向移动,然后再纵向移动,所以我们可以考虑每行维护一个splay,最后一列再维护一个splay。
    但是考虑到n和m的规模都是(3*10^5)级别的,普通的splay肯定会爆空间,所以我们使用动态开点的splay,对于每个节点记录一个L和一个R,如果需要splay的元素在这个区间当中,就把当前节点拆成3个,将左侧部分和右侧部分分别插入到左子树的最右边和右子树的最左边。
    然后接下来就是一些细节问题了:

    • 别忘开long long
    • splay在拆点时要特别注意判断条件
    • 小心只有一列或要出列的人在最后一列的情况

    Code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    struct Node
    {
        int s; LL L,R;
        Node* ch[2];
        inline void PU() { s=ch[0]->s+R-L+1+ch[1]->s; }
        inline int cmp(int k)
        {
            int d=k-ch[0]->s;
            return d>=1&&d<=R-L+1?-1:d>1;
        }
    };
    Node *null=new Node();
    inline Node* NN(LL L,LL R)
    {
        Node *o=new Node();
        o->L=L; o->R=R; o->s=R-L+1;
        o->ch[0]=o->ch[1]=null;
        return o;
    }
    inline void rotate(Node* &o,int d)
    {
        Node* p=o->ch[d^1];
        o->ch[d^1]=p->ch[d]; p->ch[d]=o;
        o->PU();
        p->PU();
        o=p;
    }
    void Add(Node* &o,Node *v,int d)
    {
        if(o==null) { o=v; return; }
        Add(o->ch[d],v,d);
        o->PU();
    }
    inline void cut(Node* &o,int k)
    {
        LL L=o->L,R=o->R,s=R-L+1;
        o->L=o->R=L+k-1;
        if(k-1>=1) Add(o->ch[0],NN(L,L+k-2),1);
        if(k+1<=s) Add(o->ch[1],NN(L+k,R),0);
        o->PU();
    }
    void splay(Node* &o,int k)
    {
        int d=o->cmp(k);
        if(d==-1&&o->R-o->L+1>1) cut(o,k);
        if(d==1) k-=o->ch[0]->s+1;
        if(d!=-1)
        {
            Node *p=o->ch[d];
            int d2=p->cmp(k);
            if(d2==-1&&p->R-p->L+1>1) cut(p,k);
            if(d2==1) k-=p->ch[0]->s+1;
            if(d2!=-1)
            {
                splay(p->ch[d2],k);
                if(d==d2) rotate(o,d^1);
                else rotate(o->ch[d],d);
            }
            rotate(o,d^1);
        }
    }
    inline Node* merge(Node *left,Node *right)
    {
        splay(left,left->s);
        left->ch[1]=right;
        left->PU();
        return left;
    }
    inline void split(Node *o,int k,Node* &left,Node* &right)
    {
        splay(o,k);
        left=o;
        right=o->ch[1];
        o->ch[1]=null;
        left->PU();
    }
    inline void dfsx(Node* o)
    {
        if(o==null) return;
        dfsx(o->ch[0]);
        for(int i=o->L;i<=o->R;i++) printf("%d ",i);
        dfsx(o->ch[1]);
    }
    #define print(x) do { printf("%s: ",#x); dfsx(x); puts(""); } while(0)
    //以上为splay模板
    const int maxn=3e5+5;
    LL n,m,q;
    Node *r[maxn],*lst;
    int main()
    {
    #ifdef local
    //	freopen("testdata.in","r",stdin);
    //	freopen("pro.out","w",stdout);
        freopen("pro.in","r",stdin);
    #endif
        null->ch[0]=null->ch[1]=null; null->s=0;
        dfsx(null);
        scanf("%lld%lld%lld",&n,&m,&q);
        for(int i=1;i<=n;i++)
        {
            if(m>=2) r[i]=merge(NN(-1,-1),NN((i-1)*m+1,(i-1)*m+1+m-2));
            else r[i]=NN(-1,-1);
        }
        lst=NN(-1,-1);
        for(int i=1;i<=n;i++) lst=merge(lst,NN(i*m,i*m));
        for(int i=1;i<=q;i++)
        {
            int x,y; scanf("%d%d",&x,&y);
            if(y<m)
            {
                Node *a,*b,*c,*d,*e,*f;
                split(r[x],y,a,b);
                split(b,1,b,c);
                split(lst,x,d,e);
                split(e,1,e,f);
                printf("%lld
    ",b->L);
                r[x]=merge(merge(a,c),e);
                lst=merge(merge(d,f),b);
            }
            else
            {
                Node *a,*b,*c;
                split(lst,x,a,b);
                split(b,1,b,c);
                printf("%lld
    ",b->L);
                lst=merge(merge(a,c),b);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    Linux 进程管理
    强大的bat文件搞定系统所有问题
    Java多线程设计要点
    Linux 内核
    Linux 文件和目录管理之列出、删除、复制、移动及改名
    命令dd 及简单应用
    Transferring Files with SFTP or SCP
    简述Linux文件搜索
    加强Eclipse代码自动提示的方法
    Cisco交换机配置新手篇之端口配置
  • 原文地址:https://www.cnblogs.com/happyZYM/p/11379575.html
Copyright © 2011-2022 走看看