zoukankan      html  css  js  c++  java
  • [bzoj1552zoj2506][Cqoi2014]robotic sort 排序机械臂_非旋转Treap

    robotic sort 排序机械臂 bzoj-1552 bzoj-2506 Cqoi-2014

    题目大意:给定一个序列,让你从1到n,每次将[1,p[i]]这段区间反转,p[i]表示整个物品权值第i小的。

    注释:$1le nle 10^5$。

    想法:非旋转Treap裸题,随题目要求。只需要非旋转Treap的最基本的函数和一个查询排名的函数即可。

    最后,附上丑陋的代码... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 100010 
    #define mp make_pair
    using namespace std;
    typedef pair<int,int> par;
    struct pig
    {
        int val,id,fin_val;
    }t[N];
    int n;
    inline bool cmp1(pig x,pig y)
    {
        if(x.val!=y.val)return x.val<y.val;
        return x.id<y.id;
    }
    inline bool cmp2(pig x,pig y)
    {
        return x.id<y.id;
    }
    struct Node
    {
        int ls,rs,size,key,fa;
        bool turn;
    }a[N];
    int root;
    inline void update(int x)
    {
        int ls=a[x].ls,rs=a[x].rs;
        a[x].size=1;
        if(ls)a[x].size+=a[ls].size;
        if(rs)a[x].size+=a[rs].size;
    }
    inline void pushdown(int x)
    {
        if(a[x].turn)
        {
            swap(a[x].ls,a[x].rs);
            if(a[x].ls)a[a[x].ls].turn^=1;
            if(a[x].rs)a[a[x].rs].turn^=1;
            a[x].turn=0;
        }
    }
    int merge(int x,int y)
    {
        pushdown(x);pushdown(y);
        if(!x||!y)return x|y;
        if(a[x].key>a[y].key)
        {
            a[x].rs=merge(a[x].rs,y);
            a[a[x].rs].fa=x;
            update(x);
            return x;
        }
        a[y].ls=merge(x,a[y].ls);
        a[a[y].ls].fa=y;
        update(y);
        return y;
    }
    par split(int x,int k)
    {
        pushdown(x);
        if(!k)return mp(0,x);
        int ls=a[x].ls,rs=a[x].rs;
        if(k==a[ls].size)
        {
            a[ls].fa=0;
            a[x].ls=0;update(x);
            return mp(ls,x);
        }
        if(k==a[ls].size+1)
        {
            a[rs].fa=0;
            a[x].rs=0;update(x);
            return mp(x,rs);
        }
        if(k<a[ls].size)
        {
            par t=split(ls,k);
            a[t.first].fa=0,a[t.second].fa=x;
            a[x].ls=t.second;
            update(x);
            return mp(t.first,x);
        }
        par t=split(rs,k-a[ls].size-1);
        a[t.first].fa=x,a[t.second].fa=0;
        a[x].rs=t.first;
        update(x);
        return mp(x,t.second);
    }
    int z[N],top;
    int getrank(int x)
    {
        top=0;int t=x;
        while(t)z[++top]=t,t=a[t].fa;
        while(top)pushdown(z[top--]);
        int ans=0,flag=1;
        while(x)
        {
            if(flag)ans+=a[a[x].ls].size+1;
            flag=(x==a[a[x].fa].rs);
            x=a[x].fa;
        }
        return ans;
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)scanf("%d",&t[i].val),t[i].id=i;
        sort(t+1,t+n+1,cmp1);
        for(int i=1;i<=n;i++)t[i].fin_val=i;
        sort(t+1,t+n+1,cmp2);
        for(int i=1;i<=n;i++)
        {
            int pos=t[i].fin_val;
            a[pos].key=rand(),a[pos].size=1;
            root=merge(root,pos);
        }
        for(int i=1;i<=n;i++)
        {
            int rank=getrank(i);
            printf("%d",rank);
            if(n-i)putchar(' ');
            if(i==rank)continue;
            par t2=split(root,rank),t1=split(t2.first,i-1);
            a[t1.second].turn^=1;
            root=merge(merge(t1.first,t1.second),t2.second);
        }
        return 0;
    }
    

    小结:非旋转Treap就是比splay牛逼..

  • 相关阅读:
    CentOS 6的服务器后执行yum后发现出现Error: Cannot find a valid baseurl for repo: base解决办法
    C# 8字节byte数组转int
    Unity Packages 介绍
    开发笔记:服务端返回三/多级菜单数据的几种不同实现
    Grafana Azure Data Explorer Plug-In 中国区 ADX 支持
    Redash 连接中国区 Azure Data Explorer
    爆竹声中贺新年-- KEDA(Kubernetes Event-driven Autoscaling) 带你烟火秀
    生产随机码包含数字+字母
    关于串口通信发送组合键方法
    python 正则匹配一串字符串的负数和正数,合并两个列表为字典
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9283993.html
Copyright © 2011-2022 走看看