数列[专杀Splay版]

时间:2022-01-16 00:31:47

时间限制: 3 Sec  内存限制: 128 MB
提交: 49  解决: 7

题目描述

输入一个数列,你需要进行如下操作: 
1、 把编号为I的数值改为K 
2、 输出从小到大排序后第k个数

输入

输入文件第一行包含两个整数N、M,分别表示数列长度与操作个数。 
第二行有N个整数,为初始数列中的N个整数。 
接下来M行每行如果只有一个整数k,那么就是输出第k小数,否则两个整数I,K表示把第I个数的数值改为K。

输出

输出所有要求输出的数,每个数单独一行。

样例输入

5 3
5 3 2 1 1
4
2 6
4

样例输出

3
5

提示

N,M≤200,000
数列中所有数字的绝对值不大于100,000,000
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<ctime>
using namespace std;
const int maxn=;
int n,m;
struct node
{
int key,rev,size;
node *child[],*father;
}bst[maxn],*root;
node *pos=bst;
queue<node*>mem;
void update(node* &r)
{
if(r)
r->size=(r->child[]!=NULL?r->child[]->size:)+(r->child[]!=NULL?r->child[]->size:)+;
}
void rotate(node* &r,int b)
{
node *y=r->child[!b];
r->child[!b]=y->child[b];
y->child[b]=r;
update(r);
r=y;
update(r);
}
void newnode(node* &r,int key)
{
if(mem.empty())r=pos++;
else r=mem.front(),mem.pop();
r->key=key;
r->size=;
r->rev=rand();
r->child[]=r->child[]=NULL;
}
void insert(node* &r,int key)
{
if(!r)newnode(r,key);
else
{
bool b=r->key<key;
insert(r->child[b],key);
if(r->child[b]->rev<r->rev)
rotate(r,!b);
}
update(r);
}
void delet(node* &r,int key)
{
if(!r)return;
if(r->key==key)
{
if(r->child[]&&r->child[])
{
bool b=r->child[]->rev<r->child[]->rev;
rotate(r,b);
delet(r->child[b],key);
}
else
{
mem.push(r);
if(r->child[])r=r->child[];
else r=r->child[];
}
}
else
{
bool b=r->key<key;
delet(r->child[b],key);
}
update(r);
}
int end,len;
int read(char s[],int begin)
{
int i,ans=,f=;
for(i=begin;i<len;i++)
{
if(s[i]>=''&&s[i]<='') ans=ans*+s[i]-'';
else if(s[i]=='-')f=-;
else break;
}
if(begin==i)return ;
end=i+;
return ans*f;
}
int find(node* &r,int x)
{
if(r==NULL)return ;
if(r->child[]!=NULL&&x==r->child[]->size)return r->key;
if(!x&&r->child[]==NULL)return r->key;
if(!x)return find(r->child[],x);
if(r->child[]!=NULL&&r->child[]!=NULL)
{
int t=r->child[]->size;
if(t>x)return find(r->child[],x);
else if(t<x)return find(r->child[],x-t-);
}
else
{
if(r->child[]==NULL)return find(r->child[],x-);
if(r->child[]==NULL)return find(r->child[],x);
}
return ;
}
int a[maxn];
int main()
{
int i,j;
scanf("%d%d",&n,&m);
for(i=;i<=n;i++)
{
scanf("%d",&j);
a[i]=j;
insert(root,j);
}
char s[];
getchar();
for(i=;i<=m;i++)
{
len=;
while(len==)gets(s),len=strlen(s);
int x=read(s,),y=read(s,end);
if(y!=)
{
delet(root,a[x]);
a[x]=y;
insert(root,a[x]);
}
else
{
int ans=find(root,x-);
if(ans!=)
printf("%d\n",ans);
}
}
return ;
}