zoukankan      html  css  js  c++  java
  • 【BZOJ-1552&3506】robotic sort&排序机械臂 Splay

    1552: [Cerc2007]robotic sort

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 806  Solved: 329
    [Submit][Status][Discuss]

    Description

    Input

    输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。

    Output

    输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,Pi表示第i次操作前第i小的物品所在的位置。 注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。

    Sample Input

    6
    3 4 5 1 6 2

    Sample Output

    4 6 4 5 6 6

    HINT

    Source

    HNOI2009集训Day6

    Solution

    Splay基本操作...

    我们首先对给出的序列排序,第一关键字是编号,第二关键字是时间戳,然后用splay去维护这个有顺序的序列就可以了

    或者可以考虑维护min和pos

    Splay要常写!调的跟*一样慢

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    inline int read()
    {
        int x=0; char ch=getchar();
        while (ch<'0' || ch>'9') {ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x;
    }
    #define MAXN 100010
    int N,pos[MAXN];
    struct Node{int id,t;}a[MAXN];
    inline bool cmp(Node A,Node B) {return A.id==B.id? A.t<B.t:A.id<B.id;}
    namespace SplayTree
    {
        int size[MAXN],root,sz,fa[MAXN],son[MAXN][2]; bool rev[MAXN];
        #define ls(x) son[x][0]
        #define rs(x) son[x][1]
        inline void Update(int now) {size[now]=size[ls(now)]+size[rs(now)]+1;}
        inline void PushDown(int now)
        {
            if (!rev[now]) return;
            rev[ls(now)]^=1; rev[rs(now)]^=1; swap(ls(now),rs(now)); rev[now]=0;
        }
        inline bool Right(int now) {return son[fa[now]][1]==now;}
        inline void rotate(int now)    
        {
            PushDown(fa[now]); PushDown(now);
            int f=fa[now],gf=fa[f],wh=Right(now);
            son[f][wh]=son[now][wh^1]; fa[son[f][wh]]=f;
            fa[f]=now; son[now][wh^1]=f; fa[now]=gf;
            if (gf) son[gf][son[gf][1]==f]=now;
            Update(f); Update(now);
        }
        inline void splay(int now,int tar)
        {
            for (int f; (f=fa[now])!=tar; rotate(now))
                if (fa[f]!=tar) rotate(Right(now)==Right(f)? f:now);
            if (!tar) root=now;    
        }
        inline int GetX(int k)
        {
            int x=root;
            while (1)
                {
                    PushDown(x);
                    if (k<=size[ls(x)]) x=ls(x);
                        else if (k==size[ls(x)]+1) return x;
                            else k-=size[ls(x)]+1,x=rs(x);
                }
            return -1;
        }
        inline int GetK(int x) {splay(x,0); return size[ls(x)];}
        inline int BuildTree(int l,int r,int last)
        {
            if (r<l) return 0;
            int mid=(l+r)>>1,now=++sz;
            pos[a[mid].id]=now; fa[now]=last;
            int lson=BuildTree(l,mid-1,now),rson=BuildTree(mid+1,r,now);
            son[now][0]=lson; son[now][1]=rson;
            Update(now);
            return now;
        }
        inline void Reverse(int l,int r) {splay(l,0),splay(r,l); rev[ls(rs(root))]^=1;}
        inline void Init() {root=BuildTree(1,N+2,0);}
    }
    int main()
    {
        N=read();
        for (int i=2,t=0; i<=N+1; i++) a[i].id=read(),a[i].t=++t;
        a[1].id=0; a[N+2].id=N+2; 
        stable_sort(a+2,a+N+2,cmp);
        for (int i=1; i<=N; i++) a[a[i+1].t+1].id=i;
    //    for (int i=1; i<=N+2; i++) printf("%d ",a[i].id); puts("");
        SplayTree::Init();
        for (int i=1; i<=N; i++)
            {
                int loc=SplayTree::GetK(pos[i]);
                int x=SplayTree::GetX(i),y=SplayTree::GetX(loc+2);
    //            printf("%d %d
    ",x,y);
                SplayTree::Reverse(x,y);
                printf("%d%c",loc,i!=N? ' ':'
    ');
            }
        return 0;
    }

    和char哥,龙哥,连坐调splay...感觉智障++

  • 相关阅读:
    Informix日期获取上周上月昨天去年SQL
    Oracle-创建一个DBLink的方法
    Kafka-Partitions与Replication Factor 调整准则
    Linux-删除文件空间不释放问题解决
    Redhat7-Oracle-sqlldr-安装配置
    Centos7-安装oracle客户端11.2.0.4
    Centos7-单机安装jumpserver
    Redhat6.4-yum本地源安装配置
    Linux-zip unzip 命令日常使用
    xxl-job日志
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5859022.html
Copyright © 2011-2022 走看看