刷題總結 排序機械臂(石室中學oj)(splay)

2022-05-23 15:00:12 字數 1790 閱讀 4979

為了把工廠中高低不等的物品按從低到高排好序,工程師發明了一種排序機械臂。它遵循乙個簡單的排序規則,第一次操作找到最低的物品位置 p1,並把從左起第 1 個至第 p1 個之間的物品反序;第二次找到第二低的物品的位置 p2,並把左起第二個至第 p2 個之間的物品反序……最終所有的物品都會被排好序。 

上圖給出乙個示例,第一次操作前,最低物品在位置 4,於是把第 1 至第 4 個物品反序;第二次操作前,第二低的物品在位置 6,於是把第 2 至第 6 的物品反序……

你的任務是編寫乙個程式,確定操作序列,即每次操作前第 i 低的物品所在的位置pi,以便機械臂工作。需要注意的是,如果有高度相同的物品,必須保證排序後他們的相對位置關係與初始時相同。 

第一行包含乙個正整數 n,表示需要排序的物品數量。 

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

輸出一行包含 n 個空格分隔的整數 pi。 

輸入  [複製]

3 4 5 1 6 2

輸出

4 6 4 5 6 6

輸入  [複製]

3 3 2 1

輸出

4 2 4 4

【資料範圍】

對於 30% 的資料:1≤n≤1000 

對於 100% 的資料:1≤n≤100000,1≤ai≤2×109 

利用splay進行區間反轉模版題:若要反轉i-j內的區間(包括i,j)先找到下標為i-1的點splay到根節點,再找到j+1的點splay到i-1下方,將j+1的左子樹的子樹進行swap即可(注意打標記)

#include#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int n=100005

;int father[n],son[n][2

],tag[n],size[n],root,tot,num[n];

intn,rank[n];

struct

node

a[n];

intr()

bool

cmp(node a,node b)

inline

void pushdown(int

now)

}inline

void update(int

now)

}inline

intget(int

now)

inline

void rotate(int

now)

inline

void splay(int now,int

to)

if(!to) root=now;

}inline

void insert(int

x)

last=now;

now=son[now][1

]; }

}inline

int find(int

x) x-=temp;now=son[now][1

]; }

}}intmain()

return0;

}

排序機械臂 splay

給定乙個長度為n的序列,需要進行n次交換操作.第i次操作需要將區間 i,pi 進行翻轉,其中pi表示序列第i小的數字的下標.特別的,如果序列中有重複的元素,則認為在初始序列中下標小的數字更小.題目中由於涉及到了區間翻轉,我們應當聯想到是否可以採用 平衡樹 解決該問題.首先有個疑問,我們應當如何維護序...

CQOI2014 排序機械臂

題目鏈結 洛谷 p3165 bzoj 3506 解析 如果用 splay 做,需要先排序,記錄每個點被選中的順序。考慮到 fhq treap 的 heap 性質,直接將結點的 key 值設為每個物品的高度。充分利用小根堆的性質,使每次被選中的結點一定是根結點。當資料單調時,操作總複雜度為 o n 但...

CQOI2014 排序機械臂

一道很水很水的題,splay樹儲存乙個最小值,每次查詢最小值所在的位置,旋轉到根,輸出它在第幾位。然後將它之前的節點打上翻轉標記,維護一下即可。注意這道題要先排序,因為翻轉操作之後就不知到它原來的位置了。1 never forget why you start 2 include3 include4...