啊,终于敲熟了无旋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(' ');break; case 4:print(Findkth(x));print(' ');break; case 5:print(Findkth(Getkth(root,x)));print(' ');break; case 6:print(Findkth(Getkth(root,x+1)+1));print(' ');break; } } flush(); return 0; }
读入优化在哪里都能用,开心。