Luogu4402 機械排序

2022-08-13 22:21:12 字數 1657 閱讀 4709

題目藍鏈

給你乙個長度為\(n\)的序列,你要對它進行操作,規則如下

第\(i\)次操作時,找到區間\([1, n]\)中第\(i\)小的數的位置\(p_i\),並翻轉區間\([i, p_i]\)

最後輸出操作序列\(p_i\)

很久沒有做過\(splay\)的題目了,來打個板子複習一下

我們可以把題意轉換一下:第\(i\)次操作時,找到區間\([i, n]\)中最小的數的位置\(p_i\),並翻轉區間\([i, p_i]\)

然後這相當於就是乙個排序 雖然我沒用這個做法

我的做法特別簡單粗暴,就是照著題意模擬

每次直接找整段區間最小值的位置,然後用\(splay\)模擬題目的翻轉,然後把這個最小值設為\(inf\)

\(p_i​\)序列就邊操作邊輸出就可以了

#include using namespace std;

#define fst first

#define snd second

#define mp make_pair

#define squ(x) ((ll)(x) * (x))

#define debug(...) fprintf(stderr, __va_args__)

typedef long long ll;

typedef pairpii;

templateinline bool chkmax(t &a, const t &b)

templateinline bool chkmin(t &a, const t &b)

inline int read()

const int maxn = 1e5 + 10;

const int inf = 1e9;

int n, a[maxn];

namespace splay

}a[maxn];

#define ls(x) a[x].son[0]

#define rs(x) a[x].son[1]

#define fa(x) a[x].f

inline void push_up(int x)

inline void push_down(int x)

} inline bool chk(int x)

inline void link(int x, int y, int f)

inline void rotate(int x)

inline void splay(int x, int y)

if (!y) rt = x; /**/

} inline void build(int &x, int l, int r)

inline int rank(int k)

return x;

} inline void reverse(int x, int y)

inline void change(int x)

inline int query() /**/

x = (a[ls(x)].s < a[rs(x)].s ? ls(x) : (res += a[ls(x)].sz + 1, rs(x)));

} return res + 1; }}

int main()

return 0;

}

排序機械臂 splay

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

luogu1155 雙棧排序

題目描述 tom最近在研究乙個有趣的排序問題。如圖所示,通過2個棧s1和s2,tom希望借助以下4種操作實現將輸入序列公升序排序。操作a如果輸入序列不為空,將第乙個元素壓入棧s1 操作b如果棧s1不為空,將s1棧頂元素彈出至輸出序列 操作c如果輸入序列不為空,將第乙個元素壓入棧s2 操作d如果棧s2...

LUOGU 3089 字尾排序(模板)

傳送門 這是乙個神奇的演算法,sa i 表示排名第i為的元素是啥,rk i 表示第i個元素排名是啥。然後使用基數排序 倍增的思想去處理。主要是參考的這位大佬的部落格 include include include include using namespace std const int maxn ...