啊,终于敲熟了无旋Treap的板子。自己太弱了。垃圾码风吃枣药丸。(自己抄代码的能力又有提高了)
#include<cstdio>
#include<cctype>
#include<cstdlib>
using namespace std;
namespace Treap{
const int maxn=100100,inf=0x7fffffff;
struct Treap{
Treap *ch[2];
#define ls ch[0]
#define rs ch[1]
int key,val,size;
Treap(int v){size=1,val=v,key=rand();ls=rs=0;}
inline void tain(){size=1+(ls?ls->size:0)+(rs?rs->size:0);}
}*root;
typedef struct pair{Treap *first,*second;pair(Treap *_f,Treap *_s){this->first=_f,this->second=_s;}pair(){}}D;
inline int size(Treap *o){return o?o->size:0;}
Treap *Merge(Treap *a,Treap *b)
{
if(!a)return b;
if(!b)return a;
if(a->key>b->key){a->rs=Merge(a->rs,b),a->tain();return a;}
b->ls=Merge(a,b->ls),b->tain();return b;
}
D Split(Treap *o,int k)
{
if(!o)return D(0,0);
D y;
if(size(o->ls)>=k){y=Split(o->ls,k);o->ls=y.second;o->tain();y.second=o;return y;}
y=Split(o->rs,k-size(o->ls)-1);o->rs=y.first;o->tain();y.first=o;return y;
}
int Getkth(Treap *o,int v)
{
if(!o)return 0;
return o->val>=v?Getkth(o->ls,v):Getkth(o->rs,v)+size(o->ls)+1;
}
inline int Findkth(int k)
{
D x=Split(root,k-1);
D y=Split(x.second,1);
Treap* ans=y.first;
root=Merge(Merge(x.first,ans),y.second);
return ans?ans->val:0;
}
inline void Insert(int v)
{
int k=Getkth(root,v);
D x=Split(root,k);
Treap* o=new Treap(v);
root=Merge(Merge(x.first,o),x.second);
}
void Delete(int v)
{
int k=Getkth(root,v);
D x=Split(root,k);
D y=Split(x.second,1);
root=Merge(x.first,y.second);
}
#undef ls
#undef rs
}
namespace IO{
const int InputBufferSize = 67108864;//输入缓冲区大小
const int OutputBufferSize = 67108864;//输出缓冲区大小
namespace input{
char buffer[InputBufferSize],*s,*eof;
inline void init()
{
s=buffer;
eof=s+fread(buffer,1,InputBufferSize,stdin);
}
inline bool read(int &x)
{
while(!isdigit(*s)&&*s!='-')s++;
if(eof<=s)return false;
x=0;
register int flag=1;
if(*s=='-')flag=-1,s++;
while(isdigit(*s))x=x*10+*s++-'0';
x*=flag;
return true;
}
inline bool read(char *str)
{
*str=0;
while(isspace(*s))s++;
if(eof<s)return false;
while(!isspace(*s))*str=0,*str=*s,str++,s++;
*str=0;
return true;
}
}
namespace output{
char buffer[OutputBufferSize];
char *s=buffer;
inline void flush()
{
fwrite(buffer,1,s-buffer,stdout);
s=buffer;
}
inline void print(const char ch)
{
if(s-buffer>OutputBufferSize-2)flush();
*s++=ch;
}
inline void print(char *str)){while(*str!=0)print(char(*str++));}
inline void print(int x)
{
char buf[25]= {0},*p=buf;
if(x<0)print('-'),x=-x;
if(x==0)print('0');
while(x)*(++p)=x%10,x/=10;
while(p!=buf)print(char(*(p--)+'0'));
}
}
using namespace input;
using namespace output;
}
using namespace IO;
using namespace Treap;
int main()
{
init();
int m,opt,x;read(m);
while(m--)
{
read(opt);read(x);
switch(opt)
{
case 1:Insert(x);break;
case 2:Delete(x);break;
case 3:print(Getkth(root,x)+1);print('\n');break;
case 4:print(Findkth(x));print('\n');break;
case 5:print(Findkth(Getkth(root,x)));print('\n');break;
case 6:print(Findkth(Getkth(root,x+1)+1));print('\n');break;
}
}
flush();
return 0;
}
读入优化在哪里都能用,开心。