zoukankan      html  css  js  c++  java
  • BZOJ3506: [Cqoi2014]排序机械臂

    BZOJ3506: [Cqoi2014]排序机械臂

    额,$BZOJ$上没有题面。。。

    本蒟蒻表示没钱氪金。。。

    这里附上洛谷的题面:

    洛谷P3165 [CQOI2014]排序机械臂

    题目描述

    为了把工厂中高低不等的物品按从低到高排好序,工程师发明了一种排序机械臂。

    它遵循一个简单的排序规则,第一次操作找到高度最低的物品的位置 $P_1$ ,并把左起第一个物品至 $P_1$ 间的物品 (即区间 $[1,P_1]$间的物品) 反序;第二次找到第二低的物品的位置 $P_2$ ,并把左起第二个至 $P_2$ 间的物品 (即区间 $[2,P_2]$ 间的物品) 反序……最终所有的物品都会被排好序。

    样例说明

    上图给出有六个物品的示例,第一次操作前,高度最低的物品在位置 $4$ ,于是把第一至第四的物品反序;第二次操作前,第二低的物品在位罝六,于是把第二至六的物品反序……

    你的任务便是编写一个程序,确定一个操作序列,即每次操作前第$ i$ 低的物品所在位置$ P_i$,以便机械臂工作。

    需要注意的是,如果有高度相同的物品,必须保证排序后它们的相对位置关系与初始时相同。

    输入输出格式

    输入格式:

    第一行包含正整数n,表示需要排序的物品数星。

    第二行包含n个空格分隔的整数$P_i$,表示每个物品的高度。

    输出格式:

    输出一行包含n个空格分隔的整数Pi。

    输入输出样例

    输入样例#1: 复制
    6
    3 4 5 1 6 2
    输出样例#1: 复制
    4 6 4 5 6 6

    说明

    N<=100000

    Pi<=10^7


    题解Here!

    看到区间翻转——区间神器$Splay$!

    但是!高度是无序的,而$Splay$是有序的,怎么办呢?

    我们可以用结构体存高度与 下标,然后排序。

    于是高度就可以丢一边了。。。

    具体看代码中的$splay::reverse$ 。

    注意:

    1. 头尾设两个哨兵节点。
    2. $splay$每次都要$pushdown$一次(巨坑)!

    附代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define MAXN 100010
    #define MAX 999999999
    using namespace std;
    int n,size=1,root=0;
    struct node{
        int x,id;
    }b[MAXN];
    namespace splay{
        struct Splay{
            int f,s,flag,son[2];
            int v;
        }a[MAXN];
        inline void clean(int rt){
            a[rt].son[0]=a[rt].son[1]=a[rt].f=a[rt].s=a[rt].flag=a[rt].v=0;
        }
        inline void pushup(int rt){
            if(!rt)return;
            a[rt].s=a[a[rt].son[0]].s+a[a[rt].son[1]].s+1;
        }
        inline void pushdown(int rt){
            if(!rt||!a[rt].flag)return;
            a[a[rt].son[0]].flag^=1;a[a[rt].son[1]].flag^=1;a[rt].flag^=1;
            swap(a[rt].son[0],a[rt].son[1]);
        }
        inline void turn(int rt,int k){
            int x=a[rt].f,y=a[x].f;
            a[x].son[k^1]=a[rt].son[k];
            if(a[rt].son[k])a[a[rt].son[k]].f=x;
            a[rt].f=y;
            if(y)a[y].son[a[y].son[1]==x]=rt;
            a[x].f=rt;
            a[rt].son[k]=x;
            pushup(x);pushup(rt);
        }
        void splay(int rt,int ancestry){
            while(a[rt].f!=ancestry){
                int x=a[rt].f,y=a[x].f;
                pushdown(y);pushdown(x);pushdown(rt);
                if(y==ancestry)turn(rt,a[x].son[0]==rt);
                else{
                    int k=a[y].son[0]==x?1:0;
                    if(a[x].son[k]==rt){turn(rt,k^1);turn(rt,k);}
                    else{turn(x,k);turn(rt,k);}
                }
            }
            if(ancestry==0)root=rt;
        }
        inline int newnode(int x){
            int rt=size++;
            clean(rt);
            a[rt].v=x;a[rt].s=1;
            return rt;
        }
        int buildtree(int l,int r){
            if(l>r)return 0;
            int mid=l+r>>1,lson=0,rson=0;
            lson=buildtree(l,mid-1);
            int rt=newnode(b[mid].x);
            rson=buildtree(mid+1,r);
            a[rt].son[0]=lson;
            a[rt].son[1]=rson;
            if(lson)a[lson].f=rt;
            if(rson)a[rson].f=rt;
            pushup(rt);
            return rt;
        }
        int kth(int rt,int k){
            if(a[rt].s<k)return 0;
            while(1){
                pushdown(rt);
                int y=a[rt].son[0];
                if(k>a[y].s+1){
                    k-=a[y].s+1;
                    rt=a[rt].son[1];
                }
                else if(k<=a[y].s)rt=y;
                else return rt;
            }
        }
        inline void reverse(int i){
            splay(b[i].id+1,0);
            int s=a[a[root].son[0]].s;
            printf("%d ",s);
            int front=kth(root,i),next=kth(root,s+2);
            splay(front,0);splay(next,front);
            a[a[next].son[0]].flag^=1;
        }
    }
    inline int read(){
    	int date=0,w=1;char c=0;
    	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    	return date*w;
    }
    bool cmp(const node &x,const node &y){
        if(x.x==y.x)return x.id<y.id;
        return x.x<y.x;
    }
    void init(){
        n=read();
        for(int i=1;i<=n;i++){
            b[i].x=read();
            b[i].id=i;
        }
        b[0].x=-MAX;b[0].id=1;
        b[n+1].x=MAX;b[n+1].id=n+1;
        sort(b+1,b+n+1,cmp);
        root=splay::buildtree(0,n+1);
        for(int i=1;i<=n-1;i++)splay::reverse(i);
        printf("%d
    ",n);
    }
    int main(){
        init();
    	return 0;
    }
    
  • 相关阅读:
    Proj THUDBFuzz Paper Reading: PMFuzz: Test Case Generation for Persistent Memory Programs
    入围 WF 后训练记
    算法竞赛历程
    2021 多校 杭电 第十场
    2021 多校 杭电 第九场
    2021 多校 牛客 第十场
    2021 多校 牛客 第九场
    2021 多校 杭电 第八场
    2021 多校 杭电 第六场
    2021 多校 杭电 第七场
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9940392.html
Copyright © 2011-2022 走看看