zoukankan      html  css  js  c++  java
  • HDU 1890 Robotic Sort

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890

    【题意】
        给你n个数,每次将第i个位置到第i大的数所在位置之间的数进行翻转,模拟一种排序的操作,输出的是第i次操作第i大的数所在的位置。

    【分析】

         这题和2012天津现场赛的K题类似,用Splay Tree 来记录节点间的相对左右关系,树的中序就是原数列。每个节点记录以自己为根的子树有多少个节点,这样就可以很快知道一个数的左边右多少树了。每次操作后要删除第i大数的节点,根据题目要求元素要用stable_sort排序,并记录节点指针地址,这样的话第i个答案就是 i+path[i-1].t->left->data。

         由于还要求将一段数列逆转,对于这段数列中的每个元素节点,其实就是把左右子树对调下就可以了。为了提高效率,这里要像线段树样打懒惰标记,就涉及到标记的传递和数据的更新了,一定要按合适的顺序和在合适的地方来操作。另外删除节点的时候是直接利用节点地址的,那无法保证节点上方的懒惰标记已经传递下来,所以先要从根到当前节点传递下。

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <algorithm>
      5 using namespace std;
      6 struct pair
      7 {
      8     int data;
      9     void *t;
     10     bool operator <(const pair & a) const
     11     {
     12         return data<a.data;
     13     }
     14 }path[100002];
     15 struct spt
     16 {
     17     spt(){root=NULL;}
     18     struct node
     19     {
     20         int data;
     21         bool flip;
     22         node *left,*right,*father;
     23         node(int d=0,node* a=NULL,node *b=NULL,node *c=NULL):data(d),left(a),right(b),father(c),flip(false){}
     24     }*root;
     25     void pushup(node *root)
     26     {
     27         if (root==NULL) return;
     28         pushup(root->father);
     29         pushdown(root);
     30     }
     31     void pushdown(node *k)
     32     {
     33         if (k==NULL) return;
     34         if (!k->flip) return;
     35         node *t=k->left;
     36         k->left=k->right;
     37         k->right=t;
     38         if (k->left) k->left->flip^=1;
     39         if (k->right) k->right->flip^=1;
     40         k->flip^=1;
     41     }
     42     void update(node *k)
     43     {
     44         k->data=1;
     45         if (k->left) k->data+=k->left->data;
     46         if (k->right) k->data+=k->right->data;
     47     }
     48     void zig(node *k)
     49     {
     50         node* fa=k->father;
     51         pushdown(fa);
     52         pushdown(k);
     53         fa->left=k->right;
     54         if (k->right) k->right->father=fa;
     55         k->right=fa;
     56         k->father=fa->father;
     57         fa->father=k;
     58         update(fa);
     59         update(k);
     60         if (!k->father) return;
     61         if (k->father->left==fa)
     62             k->father->left=k;
     63         else
     64             k->father->right=k;
     65         update(k->father);
     66     }
     67     void zag(node *k)
     68     {
     69         node* fa=k->father;
     70         pushdown(fa);
     71         pushdown(k);
     72         fa->right=k->left;
     73         if (k->left) k->left->father=fa;
     74         k->left=fa;
     75         k->father=fa->father;
     76         fa->father=k;
     77         update(fa);
     78         update(k);
     79         if (!k->father) return;
     80         if (k->father->left==fa)
     81             k->father->left=k;
     82         else
     83             k->father->right=k;
     84         update(k->father);
     85     }
     86     void splay(node *k,node *&root)
     87     {
     88         pushdown(k);
     89         while (k->father)
     90         {
     91             node *fa=k->father;
     92             if (fa->father==NULL)
     93             {
     94                 if (k==fa->left) zig(k);
     95                 else zag(k);
     96             }
     97             else
     98             {
     99                 node *gf=fa->father;
    100                 if (fa==gf->left && k==fa->left)
    101                 {
    102                     zig(fa);
    103                     zig(k);
    104                 }
    105                 if (fa==gf->left && k==fa->right)
    106                 {
    107                     zag(k);
    108                     zig(k);
    109                 }
    110                 if (fa==gf->right && k==fa->left)
    111                 {
    112                     zig(k);
    113                     zag(k);
    114                 }
    115                 if (fa==gf->right && k==fa->right)
    116                 {
    117                     zag(fa);
    118                     zag(k);
    119                 }
    120             }
    121         }
    122         root=k;
    123     }
    124     node *findmax(node *&p)
    125     {
    126         node *t=p;
    127         pushdown(t);
    128         while (t->right) {t=t->right;pushdown(t);}
    129         splay(t,p);
    130         return t;
    131     }
    132     node* join(node *a,node *b)
    133     {
    134         if (a) {a->flip^=1;pushdown(a); a->father=NULL; }
    135         if (b) { pushdown(b);b->father=NULL;}
    136        if (!a || !b) return (node *)((int)a|(int)b);
    137         node *t=findmax(a);
    138         t->right=b;
    139         b->father=t;
    140         update(t);
    141         return t;
    142     }
    143     int remove(node *q)
    144     {
    145         pushup(q);
    146         splay(q,root);
    147         node *tem=root;
    148         int tt=0;
    149         if (root->left) tt=root->left->data;
    150         root=join(root->left,root->right);
    151         delete tem;
    152         return tt;
    153     }
    154     void del(node *p)
    155     {
    156         if (p==NULL) return;
    157         del(p->left);
    158         del(p->right);
    159         delete p;
    160     }
    161     void build(int l,int r,node *&root)
    162     {
    163         if (l>r || l<0) return ;
    164         int mid=(l+r)>>1;
    165         root=new node;
    166         build(l,mid-1,root->left);
    167         if (root->left) root->left->father=root;
    168         build(mid+1,r,root->right);
    169         if (root->right) root->right->father=root;
    170         path[mid].t=(void *)root;
    171         update(root);
    172     }
    173     ~spt(){del(root);}
    174 }*mysp;
    175 
    176 int main()
    177 {
    178    int n;
    179    while (~scanf("%d",&n) && n)
    180    {
    181        mysp=new spt;
    182        for (int i=0;i<n;++i)
    183        {
    184            int t;
    185            scanf("%d",&t);
    186            path[i].data=t;
    187        }
    188        mysp->build(0,n-1,mysp->root);
    189        stable_sort(path,path+n);
    190        for (int i=0;i<n-1;++i)
    191        {
    192            printf("%d ",i+mysp->remove((spt::node *)path[i].t)+1);
    193        }
    194        printf("%d
    ",mysp->remove((spt::node *)path[n-1].t)+n);
    195        delete mysp;
    196    }
    197 }
    代码
  • 相关阅读:
    在eclipse创建android project,最后一步点击finish没反应
    有哪些可以将网页另存图片的chrome插件?功能类似网页截图
    极品家丁—优酷全网独播喜剧
    如何安装chrome扩展?比如json-handle插件如何安装
    安装用户脚本的福音:Tampermonkey(油猴)
    多微博账号同时发微博的插件--fawave
    正能量-真正男子汉2
    如何看待优酷广告?
    秋雨连绵思晚天
    如何用Postman组装Request并且查看Response
  • 原文地址:https://www.cnblogs.com/wuminye/p/3262394.html
Copyright © 2011-2022 走看看