• 【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...感觉智障++

  • 相关阅读:
    vite启用host代理,自动无限刷新问题
    机器人语音交互
    让or使用索引
    leetcode 77. Combinations 组合(中等)
    leetcode 257. Binary Tree Paths 二叉树的所有路径(简单)
    leetcode 934. Shortest Bridge 最短的桥(中等)
    为什么 SQL 语句使用了索引,但却还是慢查询?
    leetcode 47. Permutations II 全排列 II(中等)
    leetcode 79. Word Search 单词搜索
    leetcode 126. Word Ladder II 单词接龙 II(困难)
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5859022.html
Copyright © 2020-2023  润新知