红果果的treap模板题。。。白书版treap
Time Limit: 2000MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
Description
English | Vietnamese |
In this problem, you have to maintain a dynamic set of numbers which support the two fundamental operations
- INSERT(S,x): if x is not in S, insert x into S
- DELETE(S,x): if x is in S, delete x from S
and the two type of queries
- K-TH(S) : return the k-th smallest element of S
- COUNT(S,x): return the number of elements of S smaller than x
Input
- Line 1: Q (1 ≤ Q ≤ 200000), the number of operations
- In the next Q lines, the first token of each line is a character I, D, K or C meaning that the corresponding operation is INSERT, DELETE, K-TH or COUNT, respectively, following by a whitespace and an integer which is the parameter for that operation.
If the parameter is a value x, it is guaranteed that 0 ≤ |x| ≤ 109. If the parameter is an index k, it is guaranteed that 1 ≤ k ≤ 109.
Output
For each query, print the corresponding result in a single line. In particular, for the queries K-TH, if k is larger than the number of elements in S, print the word 'invalid'.
Sample Input
Input 8 I -1 I -1 I 2 C 0 K 2 D -1 K 1 K 2 Output 1 2 2 invalid
Source
©
VNOI
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
struct Node
{
Node * ch[2];
int r,s,v;
int cmp(int x)
{
if(x==v) return -1;
return (x<v)?0:1;
}
void maintain()
{
s=1+ch[0]->s+ch[1]->s;
}
};
Node* null ;
void init()
{
null=new Node();
null->s=0;
null->ch[0]=null->ch[1]=null;
srand(time(NULL));
}
void rotate(Node* &o,int d)
{
Node* k=o->ch[1^d];
o->ch[1^d]=k->ch[d];
k->ch[d]=o;
o->maintain();
k->maintain();
o=k;
}
void insert(Node* &o,int x)
{
if(o==null)
{
o=new Node();
o->ch[0]=o->ch[1]=null;
o->v=x;o->r=rand();o->s=1;
}
else
{
int d=o->cmp(x);
if(d==-1) return ;
insert(o->ch[d],x);
if(o->r < o->ch[d]->r) rotate(o,d^1);
}
o->maintain();
}
void remove(Node* &o,int x)
{
int d=o->cmp(x);
if(d==-1)
{
Node* u=o;
if(o->ch[0]!=null&&o->ch[1]!=null)
{
int d2=(o->ch[0]->r>o->ch[1]->r)?1:0;
rotate(o,d2);
remove(o->ch[d2],x);
}
else
{
if(o->ch[0]==null) o=o->ch[1];
else o=o->ch[0];
delete u;
}
}
else remove(o->ch[d],x);
if(o!=null) o->maintain();
}
int find(Node* o,int x)
{
while(o!=null)
{
int d=o->cmp(x);
if(d==-1) return 1;
o=o->ch[d];
}
return 0;
}
int Kth(Node* o,int k)///kth small
{
while(o!=null)
{
int s=o->ch[0]->s;
if(k==s+1) return o->v;
else if(k<=s) o=o->ch[0];
else
{
o=o->ch[1]; k=k-s-1;
}
}
return -INF;
}
int Count(Node* o,int x)
{
int ret=0;
while(o!=null)
{
if(x>o->v)
{
ret+=o->ch[0]->s+1;
o=o->ch[1];
}
else o=o->ch[0];
}
return ret;
}
int main()
{
int q;
scanf("%d",&q);
init();
Node* root=null;
while(q--)
{
char cmd[3];int nb;
scanf("%s%d",cmd,&nb);
if(cmd[0]=='I'&&find(root,nb)==0)
{
insert(root,nb);
}
else if(cmd[0]=='D'&&find(root,nb)==1)
{
remove(root,nb);
}
else if(cmd[0]=='K')
{
int temp=Kth(root,nb);
if(temp==-INF) puts("invalid");
else printf("%d\n",temp);
}
else if(cmd[0]=='C')
{
printf("%d\n",Count(root,nb));
}
}
return 0;
}