• P3165 [CQOI2014]排序机械臂


    P3165 [CQOI2014]排序机械臂

    题目描述

    为了把工厂中高低不等的物品按从低到高排好序,工程师发明了一种排序机械臂。它遵循一个简单的排序规则,第一次操作找到摄低的物品的位置P1,并把左起第一个至P1间的物品反序;第二次找到第二低的物品的位置P2,并把左起第二个至P2间的物品反序...最终所有的物品都会被排好序。

    上图给出_个示例,第_次操作前,菝低的物品在位置4,于是把第1至4的物品反序;第二次操作前,第二低的物品在位罝6,于是把第2至6的物品反序...

    你的任务便是编写一个程序,确定一个操作序列,即每次操作前第i低的物品所在位置Pi,以便机械臂工作。需要注意的是,如果有高度相同的物品,必须保证排序后它们的相对位置关系与初始时相同。

    输入输出格式

    输入格式:

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

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

    输出格式:

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

    输入输出样例

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

    code

    神奇的splay

      1 #include<cstdio>
      2 #include<algorithm>
      3 
      4 using namespace std;
      5 
      6 const int N = 500100;
      7 const int INF = 1e9;
      8 
      9 int data[N],siz[N],mn[N],pos[N],tag[N],ch[N][2],fa[N],st[N];
     10 int Root,top;
     11 
     12 struct Data{
     13     int x,p;
     14 }d[N];
     15 
     16 inline char nc() {
     17     static char buf[100000],*p1 = buf,*p2 = buf;
     18     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF : *p1++;
     19 }
     20 inline int read() {
     21     int x = 0,f = 1;char ch = nc();
     22     for (; ch<'0'||ch>'9'; ch = nc())
     23         if (ch=='-') f = -1;
     24     for (; ch>='0'&&ch<='9'; ch = nc())
     25         x = x * 10 + ch - '0';
     26     return x * f;
     27 }
     28 bool cmp1(Data a,Data b) {
     29     if (a.x==b.x) return a.p < b.p;
     30     return a.x < b.x;
     31 }
     32 bool cmp2(Data a,Data b) {
     33     return a.p < b.p;
     34 }
     35 inline void pushup(int x) {
     36     int l = ch[x][0],r = ch[x][1];
     37     mn[x] = data[x],pos[x] = x;
     38     if (mn[l] < mn[x]) mn[x] = mn[l],pos[x] = pos[l];
     39     if (mn[r] < mn[x]) mn[x] = mn[r],pos[x] = pos[r];//-
     40     siz[x] = siz[l] + siz[r] + 1;
     41 }
     42 inline void pushdown(int x) {
     43     if (tag[x]) {
     44         tag[ch[x][0]] ^= 1;
     45         tag[ch[x][1]] ^= 1;
     46         swap(ch[x][0],ch[x][1]);
     47         tag[x] ^= 1;
     48     }
     49 }
     50 inline int son(int x) {
     51     return x == ch[fa[x]][1]; //-
     52 }
     53 inline void rotate(int x) {
     54     int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
     55     if (z) ch[z][c] = x;else Root = x;fa[x] = z; //-
     56     ch[x][!b] = y;fa[y] = x;
     57     ch[y][b] = a;if (a) fa[a] = y;
     58     pushup(y);pushup(x);
     59 }
     60 inline void splay(int x,int rt) {
     61     top = 0;int p = x;//--
     62     while (p) st[++top] = p,p = fa[p];
     63     while (top) pushdown(st[top]),top--;
     64     while (fa[x] != rt) {
     65         int y = fa[x],z = fa[y];
     66         if (z==rt) rotate(x);
     67         else {
     68             if (son(x)==son(y)) rotate(y),rotate(x);
     69             else rotate(x),rotate(x);
     70         }
     71     }
     72 }
     73 inline int getkth(int k) {
     74     int p = Root;
     75     while (true) {
     76         pushdown(p);
     77         if (k == siz[ch[p][0]] + 1) return p;
     78         if (ch[p][0] && siz[ch[p][0]] >= k) p = ch[p][0];
     79         else {
     80             k -= ((ch[p][0] ? siz[ch[p][0]] : 0) + 1);
     81             p = ch[p][1];
     82         }
     83     }
     84 }
     85 inline int getmnpos(int l,int r) {
     86     int L = getkth(l),R = getkth(r+2);
     87     splay(L,0);
     88     splay(R,L);
     89     return pos[ch[R][0]];
     90 }
     91 inline void rever(int l,int r) {
     92     int L = getkth(l),R = getkth(r+2);
     93     splay(L,0);splay(R,L);
     94     tag[ch[R][0]] ^= 1;
     95 }
     96 int build(int l,int r) {
     97     if (l > r) return 0;
     98     /*if (l==r) {
     99         siz[l] = 1;data[l] = mn[l] = d[l].x;pos[l] = l;
    100         return l;
    101     }*/
    102     int mid = (l + r) >> 1;
    103     int t = build(l,mid-1);
    104     fa[t] = mid;ch[mid][0] = t;
    105     t = build(mid+1,r);
    106     fa[t] = mid;ch[mid][1] = t;
    107     data[mid] = d[mid].x; //= mn[mid]pos[mid] = mid;
    108     pushup(mid);
    109     return mid;
    110 }
    111 
    112 int main() {
    113     int n = read();
    114     d[1].x = d[n+2].x = mn[0] = INF;
    115     for (int i=2; i<=n+1; ++i) 
    116         d[i].x = read(),d[i].p = i;
    117     sort(d+2,d+n+2,cmp1);
    118     for (int i=2; i<=n+1; ++i) 
    119         d[i].x = i - 1; // 没有相等的 
    120     sort(d+2,d+n+2,cmp2);
    121     Root = build(1,n+2);
    122     for (int i=1; i<=n; ++i) {
    123         int x = getmnpos(i,n);
    124         splay(x,0);
    125         printf("%d ",siz[ch[x][0]]); // siz[ch[x][0]] + 1 - 1
    126         rever(i,siz[ch[x][0]]);
    127     }
    128     return 0;
    129 }
  • 相关阅读:
    POJ C程序设计进阶 编程题#4:Tomorrow never knows?
    POJ C程序设计进阶 编程题#3: 发票统计
    深度学习笔记(10)- 控制中心之电源管理、鼠标和触控板、键盘和语言
    深度学习笔记(09)- 控制中心之时间设置
    深度学习笔记(08)- 控制中心之网络设置
    深度学习笔记(07)- 控制中心之声音设置
    深度学习笔记(06)- 控制中心之个性化设置
    深度学习笔记(05)- 控制中心之显示与默认程序
    深度学习笔记(04)- 控制中心之首页与用户管理
    深度学习笔记(03)- 启动器
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8010619.html
Copyright © 2020-2023  润新知