1552: [Cerc2007]robotic sort
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1235 Solved: 471
[ Submit][ Status][ Discuss]
Description
Input
输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。
第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。
Output
输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,Pi表示第i次操作前第i小的物品所在的位置。
注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。
Sample Input
6
3 4 5 1 6 2
3 4 5 1 6 2
Sample Output
4 6 4 5 6 6
HINT
Source
用splay维护值最小的结点编号和它的值,然后就很暴力了,每次把区间整出来,然后先找到后输出,再强行整出要翻转的区间,暴力打标记就可以了
关于相同的东东,直接排个序离散化就可以了。。
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cmath>
#define maxn 110000
#define inf 0x7fffffff
#define ls t[p].ch[0]
#define rs t[p].ch[1]
#define pa t[p].f
using namespace std;
int read() {
char ch = getchar(); int x = 0, f = 1;
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') {x = x * 10 - '0' + ch; ch = getchar();}
return x * f;
}
struct node {
int ch[2], f; bool rev;
int v, size, mn, pos;
node() {}
node(int val, int fa, int po) {
v = mn = val; f = fa; pos = po;
size = 1; ch[0] = ch[1] = rev = 0;
}
}t[maxn]; int root, sz, n;
int wh(int p) {return t[pa].ch[1] == p;}
struct data {
int v, id;
bool operator<(const data& a) const {
return v == a.v ? id < a.id : v < a.v;
}
}a[maxn];
bool cmp(data a, data b) {return a.id < b.id;}
void paint(int p) {
swap(ls, rs); t[p].rev ^= 1;
}
void pushdown(int p) {
if(t[p].rev) {
if(ls) paint(ls);
if(rs) paint(rs);
t[p].rev = 0;
}
}
void update(int p) {
t[p].mn = t[p].v; t[p].pos = p;
for(int i = 0;i <= 1; ++i)
if(t[t[p].ch[i]].mn < t[p].mn) {
t[p].mn = t[t[p].ch[i]].mn;
t[p].pos = t[t[p].ch[i]].pos;
}
t[p].size = t[ls].size + t[rs].size + 1;
}
void Rotate(int p) {
int f = pa, g = t[pa].f, c = wh(p);
if(g) t[g].ch[wh(f)] = p; pa = g;
t[f].ch[c] = t[p].ch[c ^ 1]; if(t[f].ch[c]) t[t[f].ch[c]].f = f;
t[p].ch[c ^ 1] = f; t[f].f = p;
update(f);
}
void push_up(int p) {
if(t[p].f) push_up(t[p].f);
pushdown(p);
}
void Splay(int p, int tar) {
for(; pa != tar; Rotate(p))
if(t[pa].f != tar) Rotate(wh(p) == wh(pa) ? pa : p);
update(p);
if(tar == 0) root = p;
}
void build(int &p, int fa, int L, int R) {
int mid = L + R >> 1;
t[p = ++sz] = node(a[mid].v, fa, p);
if(L == R) return ;
if(L < mid) build(ls, p, L, mid - 1);
if(R > mid) build(rs, p, mid + 1, R);
update(p);
}
int Kth(int k) {
int p = root, lsize = 0;
while(p) {
pushdown(p);
int cur = t[ls].size + lsize;
if(k == cur + 1) return p;
if(k <= cur) p = ls;
else {
lsize = cur + 1;
p = rs;
}
}
return -1;
}
void print(int p)
{
pushdown(p);
if(ls) print(ls);
cout<<t[p].v<<" ";
if(rs) print(rs);
}
void init() {
n = read(); t[0] = node(inf , 0, 0); t[0].size = 0;
for(int i = 2;i <= n + 1; ++i) {
a[i].v = read();
a[i].id = i;
}
sort(a + 2, a + n + 2);
for(int i = 2;i <= n + 1; ++i) a[i].v =i - 1;
sort(a + 2, a + n + 2, cmp);
a[1].v = 0; a[n + 2].v = 0;
build(root, 0, 1, n + 2);
}
int get_mn(int l, int r) {
int f = Kth(l); Splay(f, 0);
int p = Kth(r + 2); Splay(p, f);
int u = t[ls].pos; push_up(u);
Splay(u, 0);
int ans = t[t[u].ch[0]].size;
return ans;
}
void Rev(int l, int r) {
int f = Kth(l); Splay(f, 0);
int p = Kth(r + 2); Splay(p, f);
paint(ls);
}
void solve() {
for(int i = 1;i <= n; ++i)
{
int ans = get_mn(i, n);
printf("%d", ans);
Rev(i, ans);
if(i != n) putchar(' ');
}
puts("");
}
int main()
{
init();
solve();
return 0;
}
/*
6
3 4 5 1 6 2
*/