大名鼎鼎的板子题w
照例先贴题面
Describtion
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)Input
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
Output
对于操作3,4,5,6每行输出一个数,表示对应答案
Sample Input
10 1 106465 4 1 1 317721 1 460929 1 644985 1 84185 1 89851 6 81968 1 492737 5 493598Sample Output
106465 84185 492737Hint
1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
此时无声胜有声【大雾
这种时候应该选择直接贴袋马w
后续可能会更新不同做法QwQ
目前为止只用带旋Treap A掉这题感觉我好菜啊w
教练我想学Splay我想学无旋Treap我想学SBT我想学替罪羊QwQ
还要AVL RBT vEBT (教练:我就不信你能学得了这么多还不滚回去打字符串去)
UPD:Splay Tree成功AC
GitHub:
Backup:
1 #include <ctime> 2 #include <queue> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <iostream> 7 #include <algorithm> 8 using namespace std; 9 10 const int INF=0x7FFFFFFF; 11 #define lch chd[0] 12 #define rch chd[1] 13 #define kch chd[k] 14 #define xch chd[k^1] 15 16 class Treap{ 17 private: 18 int v; 19 int k; 20 int s; 21 public: 22 Treap* chd[2]; 23 Treap(int v=0,Treap* l=NULL,Treap* r=NULL,int s=1,int k=rand()){ 24 this->v=v; 25 this->s=s; 26 this->k=k; 27 this->chd[0]=l; 28 this->chd[1]=r; 29 } 30 inline void Maintain(){ 31 if(this->exist()) 32 this->s=this->lch->size()+this->rch->size()+1; 33 } 34 inline int value(){ 35 return this==NULL?0:v; 36 } 37 inline int key(){ 38 return this==NULL?INF:k; 39 } 40 inline int size(){ 41 return this==NULL?0:s; 42 } 43 inline bool empty(){ 44 return this==NULL; 45 } 46 inline bool exist(){ 47 return this!=NULL; 48 } 49 }*Root=NULL; 50 51 void Insert(Treap*&,int); 52 void Delete(Treap*&,int); 53 void Rotate(Treap*&,int); 54 int Rank(int); 55 int Kth(int); 56 int Predecessor(int); 57 int Successor(int); 58 59 inline void PrintTree(){ 60 queue<Treap*> q; 61 q.push(Root); 62 while(!q.empty()){ 63 if(q.front()->empty()){ 64 puts("(v=@@@,s=@@@,k=@@@)"); 65 } 66 else{ 67 printf("(v=%d,s=%d,k=%d) ",q.front()->value(),q.front()->size(),q.front()->key()); 68 q.push(q.front()->lch); 69 q.push(q.front()->rch); 70 } 71 q.pop(); 72 } 73 printf(" "); 74 } 75 76 int main(){ 77 freopen("phs.in","r",stdin); 78 freopen("phs.out","w",stdout); 79 srand(time(NULL)); 80 int n,type,num; 81 scanf("%d",&n); 82 for(int i=0;i<n;i++){ 83 scanf("%d%d",&type,&num); 84 if(type==1) 85 Insert(Root,num); 86 else if(type==2) 87 Delete(Root,num); 88 else if(type==3) 89 printf("%d ",Rank(num)); 90 else if(type==4) 91 printf("%d ",Kth(num)); 92 else if(type==5) 93 printf("%d ",Predecessor(num)); 94 else if(type==6) 95 printf("%d ",Successor(num)); 96 // PrintTree(); 97 } 98 return 0; 99 } 100 101 void Insert(Treap* &root,int x){ 102 if(root->empty()){ 103 root=new Treap(x); 104 return; 105 } 106 else{ 107 int k=x<root->value(); 108 Insert(root->xch,x); 109 root->Maintain(); 110 if(root->xch->key()>root->key()) 111 Rotate(root,k); 112 } 113 } 114 115 void Delete(Treap* &root,int x){ 116 if(root->empty()) 117 return; 118 else{ 119 if(root->value()==x){ 120 if(root->lch->exist()&&root->rch->exist()){ 121 int k=root->lch->key()>root->rch->key(); 122 Rotate(root,k); 123 Delete(root->kch,x); 124 } 125 else{ 126 Treap* tmp=root; 127 if(root->lch->exist()) 128 root=root->lch; 129 else 130 root=root->rch; 131 delete tmp; 132 } 133 } 134 else 135 Delete(root->chd[x>=root->value()],x); 136 root->Maintain(); 137 } 138 } 139 140 inline int Rank(int x){ 141 Treap* root=Root; 142 int ans=1; 143 while(root->exist()){ 144 if(x<=root->value()) 145 root=root->lch; 146 else{ 147 ans+=root->lch->size()+1; 148 root=root->rch; 149 } 150 } 151 return ans; 152 } 153 154 inline int Kth(int x){ 155 Treap* root=Root; 156 int k; 157 while(root->exist()){ 158 k=root->lch->size()+1; 159 if(x<k) 160 root=root->lch; 161 else if(x==k) 162 return root->value(); 163 else{ 164 x-=k; 165 root=root->rch; 166 } 167 } 168 return 0; 169 } 170 171 inline int Predecessor(int x){ 172 return Kth(Rank(x)-1); 173 } 174 175 inline int Successor(int x){ 176 return Kth(Rank(x+1)); 177 } 178 179 inline void Rotate(Treap* &root,int k){ 180 Treap* tmp=root->xch; 181 root->xch=tmp->kch; 182 root->Maintain(); 183 tmp->kch=root; 184 tmp->Maintain(); 185 root=tmp; 186 }
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <iostream> 5 #include <algorithm> 6 7 #define lch chd[0] 8 #define rch chd[1] 9 #define kch chd[k] 10 #define xch chd[k^1] 11 12 const int INF=0x7FFFFFFF; 13 14 class SplayTree{ 15 private: 16 struct Node{ 17 int k; 18 int s; 19 Node* prt; 20 Node* chd[2]; 21 Node(const int& key){ 22 this->k=key; 23 this->s=1; 24 this->prt=NULL; 25 this->lch=NULL; 26 this->rch=NULL; 27 } 28 inline int size(){ 29 return this==NULL?0:this->s; 30 } 31 inline int key(){ 32 return this==NULL?0:this->k; 33 } 34 inline void Maintain(){ 35 if(this!=NULL) 36 this->s=this->lch->size()+this->rch->size()+1; 37 } 38 inline int Pos(){ 39 return this==this->prt->lch; 40 } 41 }*root; 42 43 void Rotate(Node* root,int k){ 44 Node* tmp=root->xch; 45 if(root->prt==NULL) 46 this->root=tmp; 47 else if(root->prt->lch==root) 48 root->prt->lch=tmp; 49 else 50 root->prt->rch=tmp; 51 tmp->prt=root->prt; 52 root->xch=tmp->kch; 53 if(root->xch!=NULL) 54 root->xch->prt=root; 55 tmp->kch=root; 56 root->prt=tmp; 57 root->Maintain(); 58 tmp->Maintain(); 59 } 60 61 void Splay(Node* root,Node* prt=NULL){ 62 while(root->prt!=prt){ 63 int k=root->Pos(); 64 if(root->prt->prt==prt){ 65 this->Rotate(root->prt,k); 66 } 67 else{ 68 int d=root->prt->Pos(); 69 this->Rotate(k==d?root->prt->prt:root->prt,k); 70 this->Rotate(root->prt,d); 71 } 72 } 73 } 74 public: 75 Node* Kth(int pos){ 76 Node* root=this->root; 77 while(root!=NULL){ 78 int k=root->lch->size()+1; 79 if(pos<k) 80 root=root->lch; 81 else if(pos==k) 82 return root; 83 else{ 84 pos-=k; 85 root=root->rch; 86 } 87 } 88 return NULL; 89 } 90 91 int Rank(const int& key){ 92 Node* root=this->root; 93 int rank=1; 94 while(root!=NULL){ 95 if(root->key()<key){ 96 rank+=root->lch->size()+1; 97 root=root->rch; 98 } 99 else 100 root=root->lch; 101 } 102 return rank; 103 } 104 105 void Insert(const int& key){ 106 int pos=this->Rank(key)-1; 107 this->Splay(this->Kth(pos)); 108 this->Splay(this->Kth(pos+1),this->root); 109 Node* tmp=new Node(key); 110 this->root->rch->lch=tmp; 111 tmp->prt=this->root->rch; 112 this->root->rch->Maintain(); 113 this->root->Maintain(); 114 } 115 116 void Delete(const int& key){ 117 int pos=this->Rank(key); 118 this->Splay(this->Kth(pos-1)); 119 this->Splay(this->Kth(pos+1),root); 120 delete this->root->rch->lch; 121 this->root->rch->lch=NULL; 122 this->root->rch->Maintain(); 123 this->root->Maintain(); 124 } 125 126 inline int Predecessor(const int& key){ 127 return this->Kth(this->Rank(key)-1)->key(); 128 } 129 130 inline int Successor(const int& key){ 131 return this->Kth(this->Rank(key+1))->key(); 132 } 133 134 SplayTree(){ 135 this->root=new Node(-INF); 136 this->root->rch=new Node(INF); 137 this->root->rch->prt=this->root; 138 this->root->rch->Maintain(); 139 this->root->Maintain(); 140 } 141 }; 142 143 int main(){ 144 #ifndef ASC_LOCAL 145 freopen("phs.in","r",stdin); 146 freopen("phs.out","w",stdout); 147 #endif 148 SplayTree* T=new SplayTree(); 149 int t,opt,key; 150 scanf("%d",&t); 151 while(t--){ 152 scanf("%d%d",&opt,&key); 153 if(opt==1) 154 T->Insert(key); 155 else if(opt==2) 156 T->Delete(key); 157 else if(opt==3) 158 printf("%d ",T->Rank(key)-1); 159 else if(opt==4) 160 printf("%d ",T->Kth(key+1)->key()); 161 else if(opt==5) 162 printf("%d ",T->Predecessor(key)); 163 else 164 printf("%d ",T->Successor(key)); 165 } 166 return 0; 167 }