题目传送门
解题思路
题目大意是把一个数插到当前数列的某一位后面,问最后这个数列是啥样的
据说还可以用树状数组/线段树做,咱也不想看,咱也不想学。
无旋treap的做法非常的直接,基本上会无旋treap这题也能直接写了,所以直接看代码吧。
代码
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
#define for1(i,a,b) for (int i=a;i<=b;i++)
#define for0(i,a,b) for (int i=a;i<b;i++)
#define pt(x) printf("%s = %I64d\n",#x,(ll)x)
#define maxint ((1LL<<31)-1)
#define lson ch[rt][0]
#define rson ch[rt][1]
const int N = 2e5+5;
struct fhq_treap
{
int ch[N][2];
int pri[N];
int val[N];
int size[N];
int root,sz;
void init(){
root = 0;
sz = 1;
}
int rand(){
static int seed = 1433223;
return seed = (int)(1LL*seed*233%maxint);
}
int newnode(int v){
ch[sz][0] = ch[sz][1] = 0;
pri[sz] = rand();
val[sz] = v;
size[sz] = 1;
return sz++;
}
void push_up(int rt){
size[rt] = 1 + size[lson] + size[rson];
}
int merge(int x,int y){
if (!x || !y) return x+y;
else {
if (pri[x]>pri[y]){
ch[x][1] = merge(ch[x][1],y);
push_up(x);
return x;
}
else {
ch[y][0] = merge(x,ch[y][0]);
push_up(y);
return y;
}
}
}
void split(int rt,int k,int& x,int& y){
if (!rt) x = y =0;
else {
if (k>=size[lson]+1){
x = rt;
split(ch[rt][1],k-size[lson]-1,ch[rt][1],y);
}
else {
y = rt;
split(ch[rt][0],k,x,ch[rt][0]);
}
push_up(rt);
}
}
void insert(int p,int v){
int x,y;
split(root,p,x,y);
root = merge(merge(x,newnode(v)),y);
}
bool flag;
void DE(){flag = true;dfs1(root);puts("");}
void dfs1(int rt){
if (!rt) return ;
dfs1(lson);
if (flag) flag = false;
else printf(" ");
printf("%d",val[rt]);
dfs1(rson);
}
}tp;
int main()
{
int n,p,v;
while (~scanf("%d",&n)){
tp.init();
for1(i,1,n) scanf("%d %d",&p,&v),tp.insert(p,v);
tp.DE();
}
return 0;
}