Description
The keys must be stored in a special ordered collection that can be considered as an array A, which has an infinite number of locations, numbered starting from 1. Initially all locations are empty. The following operation must be supported by the collection: Insert(L, K), where L is the location in the array and K is some positive integer value.
The operation must be processed as follows:
- If A[L] is empty, set A[L] ← K.
- If A[L] is not empty, perform Insert(L + 1, A[L]) and after that set A[L] ← K.
Given N integer numbers L1 , L2 , . . . , LN you have to output the contents of the array after a sequence of the following operations:
Insert(L1 , 1)
Insert(L2 , 2)
. . .
Insert(LN , N)
Input
Next line contains N integer numbers L i that describe Insert operations to be performed (1 <= Li <= M ).
Output
题目大意:将n个数插入一段初始为空的序列中。给出n个数插入的位置。一个数插入序列时如果位置被占,则将该位置以后连续一段的数往后顺推一位。
//=====================================================================
考虑连续一段的要求,可以用并查集维护连续的若干块。
如果直观地做就用伸展树+即时维护连续块。每插入一个数就推一段(打上懒标记),再用并查集维护连续段。
并查集要怎么运用呢?定义一个单元的父亲是这个单元所在连续块最右端+1。很明显,初始的时候fa[i]=i,因为没有一个连续块。每次往后推都把父亲指向父亲的下个节点。怎么并两个块呢?并查集路径压缩的时候就搞掉了、
所以每次插入新的数到x单元的时候只要把从这个单元到该单元所在连续块最右端(en[x]-1)的所有数构成的子树伸展到根节点的儿子的儿子就可以了。具体操作就是找到x-1和en[x]两个单元,分别伸展到根和根的右儿子,这样根的右儿子的左儿子就是要往后推得子树了。打个标记放那就行了。。。
貌似可以从后往前做。因为一个数只会被后面的数影响。额。。具体操作还没想清楚。。。求大牛指教。
这道题最后遍历树的时候我打了人工栈,不知道为什么调用递归一直莫名202,求高手指教啊、、、
Splay Tree 打得我要多蛋疼有多蛋疼。。。再加上并查集。。。。。。再加上莫名其妙的202。。。。。。。。。
注意:
Splay Tree在询问操作结束后要把询问的节点伸展到根。不然不能保证复杂度。其实不管是询问,修改,加入都要伸展。
AC CODE
{$inline on}
{$M 20000000}
program pku_2131;
var c:array[0..300000,0..1] of longint;
a,fa,num,lazy,en,ans,stack:array[0..300000] of longint;
//============================================================================
procedure prepare;inline;
var i:longint;
begin
end;
//============================================================================
function geten(x:longint):longint;inline;
begin
end;
//============================================================================
procedure push(x:longint);inline;
var g,h:longint;
begin
end;
//============================================================================
procedure rotate(var root:longint; x:longint);inline;
var y,z,p,q:longint;
begin
end;
//============================================================================
procedure splay(var root:longint; x:longint);inline;
var y,z:longint;
begin
end;
//============================================================================
function find_left(z:longint):longint;inline;
var x:longint;
begin
end;
//============================================================================
function find_right(z:longint):longint;inline;
var x:longint;
begin
end;
//============================================================================
procedure ins(x,mark:longint);
var now:longint;
begin
end;
//============================================================================
procedure main;inline;
var f1,f2,x,i,l,r:longint;
begin
end;
//============================================================================
procedure dfs(x:longint);
begin
end;
//============================================================================
procedure print;inline;
var i:longint;
begin
end;
//============================================================================
begin
end.