Bzoj3506: [Cqoi2014]排序機械臂
阿新 • • 發佈:2018-01-12
pos putc 規則 ... def 機械 空格 type 排序規則
題面
題目描述
為了把工廠中高低不等的物品按從低到高排好序,工程師發明了一種排序機械臂。它遵循一個簡單的排序規則,第一次操作找到攝低的物品的位置P1,並把左起第一個至P1間的物品反序;第二次找到第二低的物品的位置P2,並把左起第二個至P2間的物品反序...最終所有的物品都會被排好序。
你的任務便是編寫一個程序,確定一個操作序列,即每次操作前第i低的物品所在位置Pi,以便機械臂工作。需要註意的是,如果有高度相同的物品,必須保證排序後它們的相對位置關系與初始時相同。
輸入輸出格式
輸入格式:
第一行包含正整數n,表示需要排序的物品數星。
第二行包含n個空格分隔的整數ai,表示每個物品的高度。
輸出格式:
輸出一行包含n個空格分隔的整數Pi。
輸入輸出樣例
輸入樣例#1:
6
3 4 5 1 6 2
輸出樣例#1:
4 6 4 5 6 6
說明
N<=100000 ai<=10^7
Sol
每次要排序的數首先是知道的,每次就把這個位置splay一下
區間翻轉就不說了
# include <bits/stdc++.h> # define RG register # define IL inline # define Fill(a, b) memset(a, b, sizeof(a)) using namespace std; typedef long long ll; const int _(1e5 + 10); IL ll Read(){ char c = '%'; ll x = 0, z = 1; for(; c > '9' || c < '0'; c = getchar()) if(c == '-') z = -1; for(; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0'; return x * z; } int fa[_], ch[2][_], sz[_], rev[_], rt, len, n; struct Zsy{ int id, v; IL bool operator <(Zsy Orz) const{ return v != Orz.v ? v < Orz.v : id < Orz.id; } } a[_]; IL bool Son(RG int x){ return ch[1][fa[x]] == x; } IL void Update(RG int x){ sz[x] = sz[ch[0][x]] + sz[ch[1][x]] + 1; } IL void Reverse(RG int x){ rev[x] ^= 1; swap(ch[1][x], ch[0][x]); } IL void Pushdown(RG int x){ if(!rev[x]) return; Reverse(ch[0][x]); Reverse(ch[1][x]); rev[x] ^= 1; } IL void Rotate(RG int x){ RG int y = fa[x], z = fa[y], c = Son(x); Pushdown(y); Pushdown(x); ch[Son(y)][z] = x; fa[x] = z; ch[c][y] = ch[!c][x]; fa[ch[c][y]] = y; ch[!c][x] = y; fa[y] = x; Update(y); } IL void Splay(RG int x, RG int rrt){ for(RG int y = fa[x]; y != rrt; Rotate(x), y = fa[x]) if(fa[y] != rrt) Son(x) ^ Son(y) ? Rotate(x) : Rotate(y); Update(x); if(!rrt) rt = x; } IL void Build(RG int ff, RG int &x, RG int l, RG int r){ if(l > r) return; RG int mid = (l + r) >> 1; x = mid; fa[x] = ff; sz[x] = 1; Build(x, ch[0][x], l, mid - 1); Build(x, ch[1][x], mid + 1, r); Update(x); } IL int Kth(RG int k){ RG int x = rt; while(233){ Pushdown(x); if(k == sz[ch[0][x]] + 1) return x; else if(k <= sz[ch[0][x]]) x = ch[0][x]; else k -= sz[ch[0][x]] + 1, x = ch[1][x]; } } IL void Split(RG int l, RG int r){ RG int x = Kth(l - 1); Splay(x, 0); RG int y = Kth(r + 1); Splay(y, rt); Reverse(ch[0][y]); } int main(RG int argc, RG char *argv[]){ n = Read(); a[1].v = -2e9; a[n + 2].v = 2e9; a[1].id = 1; a[n + 2].id = n + 2; for(RG int i = 2; i <= n + 1; ++i) a[i].id = i, a[i].v = Read(); sort(a + 1, a + n + 3); Build(0, rt, 1, n + 2); for(RG int i = 2; i <= n + 1; ++i){ Splay(a[i].id, 0); printf("%d", sz[ch[0][rt]]); if(i != n + 1) putchar(' '); Split(i, sz[ch[0][rt]] + 1); } return 0; }
Bzoj3506: [Cqoi2014]排序機械臂