• [hdu1890] Robotic Sort [Splay]


    题面:

    传送门

    思路:

    一看到要在序列里面翻转一段区间,就知道要使用splay了

    但是这道题涉及到一个问题:如何在通过序列位置定义的splay上面查找最小值?

    (对splay的这种用法不熟悉的可以参考这篇博客

    这里提供两种方法:

    第一种,对于每一个splay节点,我们把它的键值w设为它在原序列中的排名(注意:相同的数排名不同,这一步需要离散化)

    然后再保存一个min值即可

    这样每一次我们想要在splay树中找大小最小的节点,只要不断地往min小一些的方向去走即可

    然后,当我们做完一次操作(翻转)以后,因为前面已经排好序的元素我们其实不用再管它了,所以可以把这个元素从splay中删掉

    这样,以后每次要翻转到前面去的,都是当前splay里面最小的那个元素了

    这种方式的优点在于找最小值的过程比较直观,但是需要多维护一个min值,调试难度略大

    第二种,不保存min值,而是选取另一个方法:映射

    在输入数据、离散化结束以后,我们用二叉构造的方式建splay,这个过程中会给每一个元素赋一个“这个元素在splay数组中的下标”

    我们建立一个pos数组来保存从元素到这个数组下标的映射,即pos[i]的值代表“第i个元素在splay数组当中的下标”

    这样的话,每一次操作时我们可以通过把这个已知的元素splay到根的方式,得到它在当前splay中的排名,用这个排名加上前面已经处理完了的数的个数,就得到了当前未操作序列中最小元素(也就是下一步需要操作的元素)的位置了

    然后再把它旋转、删除即可

    这种方式的优点在于没用在splay上维护更多量,缺点是时间效率可能会比较低

    Code:

    由于博主比较懒,虽然两种方法都想到了,但是只写了第二种......

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define inf 1e9
      6 using namespace std;
      7 inline int read(){
      8     int re=0,flag=1;char ch=getchar();
      9     while(ch>'9'||ch<'0'){
     10         if(ch=='-') flag=-1;
     11         ch=getchar();
     12     }
     13     while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
     14     return re*flag;
     15 }
     16 int n,m,cnt,root,pos[200010];
     17 int fa[200010],ch[200010][2],rev[200010],siz[200010],w[200010];
     18 struct node{
     19     int val,num;
     20 }a[200010];
     21 bool cmp(node l,node r){
     22     if(l.val!=r.val) return l.val<r.val;
     23     else return l.num<r.num;
     24 }
     25 bool cmp2(node l,node r){
     26     return l.num<r.num;
     27 }
     28 void _swap(int &l,int &r){l^=r;r^=l;l^=r;}
     29 void update(int x){
     30     siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
     31 }
     32 void pushrev(int x){
     33     if(!x) return;
     34     _swap(ch[x][0],ch[x][1]);
     35     rev[x]^=1;
     36 }
     37 int push(int x){
     38     if(x&&rev[x]){
     39         pushrev(ch[x][0]);pushrev(ch[x][1]);
     40         rev[x]=0;
     41     }
     42     return 1;
     43 }
     44 int get(int x){return ch[fa[x]][1]==x;}
     45 void rotate(int x){
     46     int f=fa[x],ff=fa[f],son=get(x);
     47     push(f);push(x);
     48     ch[f][son]=ch[x][son^1];
     49     if(ch[f][son]) fa[ch[f][son]]=f;
     50     fa[f]=x;ch[x][son^1]=f;
     51     fa[x]=ff;
     52     if(ff) ch[ff][ch[ff][1]==f]=x;
     53     update(f);update(x);
     54 }
     55 void splay(int x,int to){
     56     push(x);
     57     for(int f;(f=fa[x])&&(f!=to);rotate(x)){
     58         push(fa[f]);push(f);push(x);
     59         if(fa[f]!=to)
     60             rotate((get(x)==get(f))?f:x);
     61     }
     62     update(x);
     63     if(!to) root=x;
     64 }
     65 int build(int l,int r,int f){
     66     if(l>r) return 0;
     67     int cur=++cnt,mid=(l+r)>>1;
     68     fa[cur]=f;w[cur]=a[mid].val;siz[cur]=1;pos[a[mid].val]=cur;
     69     ch[cur][0]=build(l,mid-1,cur);
     70     ch[cur][1]=build(mid+1,r,cur);
     71 //    cout<<"finish build "<<mid<<ends<<cur<<ends<<ch[cur][0]<<ends<<ch[cur][1]<<endl;
     72     update(cur);return cur;
     73 }
     74 void dfs(int u){
     75     if(!u) return;
     76     dfs(ch[u][0]);
     77     cout<<u<<ends<<w[u]<<ends<<rev[u]<<ends<<ch[u][0]<<ends<<ch[u][1]<<ends<<siz[u]<<endl;
     78     dfs(ch[u][1]);
     79 }
     80 void init(){
     81     memset(fa,0,sizeof(fa));memset(ch,0,sizeof(ch));memset(rev,0,sizeof(rev));
     82     memset(siz,0,sizeof(siz));memset(w,0,sizeof(w));memset(a,0,sizeof(a));
     83     root=0,cnt=0;
     84 }
     85 int suf(){
     86     push(root);
     87     int x=ch[root][1];
     88     while(push(x)&&ch[x][0]) x=ch[x][0];
     89     return x;
     90 }
     91 void reverse(int p){
     92 //    cout<<"reverse "<<p<<endl;
     93     splay(pos[p],0);
     94     printf("%d",p-1+siz[ch[root][0]]);
     95     if(p!=n) printf(" ");
     96     int x=pos[0],y=suf();
     97     splay(x,0);splay(y,root);
     98 //    dfs(root);
     99     pushrev(ch[y][0]);
    100 }
    101 void del(int p){
    102 //    cout<<"del "<<p<<endl;
    103     splay(pos[p],0);int tmp=suf();
    104     splay(pos[0],0);splay(tmp,root);
    105     fa[ch[tmp][0]]=0;ch[tmp][0]=0;update(tmp);update(pos[0]);
    106 //    dfs(root);
    107 //    cout<<"dell "<<p<<endl;
    108 //    fa[ch[root][1]]=ch[root][0];ch[ch[root][0]][1]=ch[root][1];
    109 //    update(ch[root][0]);root=ch[root][0];fa[root]=0;
    110 //    fa[ch[root][0]]=tmp;ch[tmp][0]=ch[root][0];
    111 //    update(tmp);root=tmp;fa[tmp]=0;
    112 //    dfs(root);
    113 }
    114 int main(){
    115 //    freopen("a.txt","w",stdout);
    116     int i,t1;
    117     while(n=read()){
    118         init();
    119         for(i=1;i<=n;i++) a[i].val=read(),a[i].num=i;
    120         sort(a+1,a+n+1,cmp);
    121 //        for(i=1;i<=n;i++) cout<<a[i].val<<ends<<a[i].num<<endl;
    122         for(i=1;i<=n;i++) a[i].val=i;
    123         sort(a+1,a+n+1,cmp2);
    124         a[0].val=0;a[n+1].val=n+1;
    125 //        for(i=0;i<=n+1;i++) cout<<a[i].val<<ends;cout<<endl;
    126         root=build(0,n+1,root);
    127         for(i=1;i<=n;i++){
    128             reverse(i);del(i);
    129         }
    130         printf("
    ");
    131     }
    132 }
  • 相关阅读:
    页面显示This is the initial start page for the WebDriver server.的解决办法
    Robot Framework + Selenium library + IEDriver环境搭建
    selenium之 chromedriver与chrome版本映射表(更新至v2.38)
    Python 各种测试框架简介(三):nose
    Python 各种测试框架简介
    python 几种常用测试框架
    一步一步教你搭建和使用FitNesse
    xss 学习记录
    android root 原理
    rtd1296 mtd 设备驱动分析
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8456607.html
Copyright © 2020-2023  润新知