一个很好玩的Treap模板。
#include <cstdio>
#include <algorithm>
#include <cstdlib>
using namespace std;
const int maxx = 100000 + 100;
int n,m,num,flag,Ans,x,root;
struct Node{
int lc,rc;
int fix,v;
int cnt,size;
}T[maxx];
inline int read(){
int x=0,f=1;char c=getchar();
while(c>'9'||c<'0') {if(c == '-') f=-1; c=getchar();}
while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
void update(int i){
T[i].size = T[T[i].lc].size + T[T[i].rc].size + T[i].cnt;
}
void lturn(int &i){
int t = T[i].rc;
T[i].rc = T[t].lc;
T[t].lc = i;
T[t].size = T[i].size;
update(i);
i = t;
}
void rturn(int &i){
int t = T[i].lc;
T[i].lc = T[t].rc;
T[t].rc = i;
T[t].size = T[i].size;
update(i);
i = t;
}
void insert(int &i,int x){
if(i == 0){
num++;
i = num;
T[i].size = T[i].cnt = 1;
T[i].v = x;
T[i].fix = rand();
return;
}
T[i].size++;
if(x == T[i].v) T[i].cnt++;
if(x < T[i].v){
insert(T[i].lc,x);
if(T[T[i].lc].fix < T[i].fix) rturn(i);
}
if(x > T[i].v){
insert(T[i].rc,x);
if(T[T[i].rc].fix < T[i].fix) lturn(i);
}
}
void remove(int &i,int x){
if(i == 0) return;
if(x > T[i].v)
T[i].size--,remove(T[i].rc,x);
if(x < T[i].v)
T[i].size--,remove(T[i].lc,x);
if(x == T[i].v){
if(T[i].cnt > 1){
T[i].size--;
T[i].cnt--;
return;
}
if(T[i].lc*T[i].rc == 0)
i = T[i].lc + T[i].rc;
else if(T[T[i].lc].fix < T[T[i].rc].fix)
rturn(i),remove(i,x);
else
lturn(i),remove(i,x);
}
}
int Query_rank(int i,int x){
if(i == 0) return 0;
if(T[i].v == x) return T[T[i].lc].size+1;
if(T[i].v > x) return Query_rank(T[i].lc,x);
if(T[i].v < x) return T[T[i].lc].size + T[i].cnt + Query_rank(T[i].rc,x);
}
int Query_num(int i,int x){
if(i == 0) return 0;
if(x <= T[T[i].lc].size)
return Query_num(T[i].lc,x);
if(x > T[T[i].lc].size + T[i].cnt)
return Query_num(T[i].rc,x-T[T[i].lc].size-T[i].cnt);
else return T[i].v;
}
void Query_pro(int i,int x){
if(i == 0) return;
if(T[i].v < x){
Ans = i;
Query_pro(T[i].rc,x);
}
else Query_pro(T[i].lc,x);
}
void Query_sub(int i,int x){
if(i == 0) return;
if(T[i].v > x){
Ans = i;
Query_sub(T[i].lc,x);
}
else Query_sub(T[i].rc,x);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
flag = read();
x = read();
switch(flag){
case 1: insert(root,x);break;
case 2: remove(root,x);break;
case 3: printf("%d\n",Query_rank(root,x));break;
case 4: printf("%d\n",Query_num(root,x)); break;
case 5: Ans = 0;Query_pro(root,x);printf("%d\n",T[Ans].v);break;
case 6: Ans = 0;Query_sub(root,x);printf("%d\n",T[Ans].v);break;
default: printf(">.<");break;
}
}
return 0;
}
upt 2017.3.26 :短了..好多
#include <cstdio>
#include <algorithm>
#include <cstring>
#define Rep( i , B , E ) for(int i=B;i<=E;i++)
#define For( i , B , E ) for(int i=B;i<=E;i++)
using namespace std;
const int maxx = 100000 + 25;
int n,m,root,num,flag,ans,x;
int ch[maxx][2],v[maxx],fix[maxx],size[maxx],cnt[maxx];
namespace Treap{
void upt(int i) {size[i] = size[ch[i][0]] + size[ch[i][1]] + cnt[i];}
int chk(int a,int b) {return a == b ? 20011025 : a > b;}
void rotate(int &i,int f){
int t = ch[i][f];
ch[i][f] = ch[t][f^1];
ch[t][f^1] = i;
size[t] = size[i];
upt(i);i = t;
}
void insert(int &i,int x){
if(i == 0) {i = ++num;v[i] = x;fix[i] = rand();size[i] = cnt[i] = 1;return;}
size[i] ++ ; if(v[i] == x) {cnt[i] ++;return;}
int tmp = chk(x,v[i]); insert(ch[i][tmp] , x);
if(fix[ch[i][tmp]] < fix[i]) rotate(i,tmp);
}
void remove(int &i,int x){
if(i == 0) return;
if(v[i] != x) size[i] -- , remove(ch[i][chk(x,v[i])] , x);
if(v[i] == x){
if(cnt[i] > 1) {cnt[i] --; size[i] --; return;}
if(ch[i][0] * ch[i][1] == 0) i = ch[i][0] + ch[i][1];
else rotate( i, chk(ch[i][0],ch[i][1]) ),remove(i,x);
}
}
int Qrank(int i,int x){
if(i == 0) return 0;if(v[i] == x) return size[ch[i][0]] + 1;
return x < v[i] ? Qrank(ch[i][0],x) : size[ch[i][0]] + cnt[i] + Qrank(ch[i][1],x);
}
int order(int i,int x){
if(i == 0) return 0;
if(x > cnt[i] + size[ch[i][0]]) return order(ch[i][1] , x - cnt[i] - size[ch[i][0]]);
else return x <= size[ch[i][0]] ? order(ch[i][0] , x) : v[i];
}
void Query(int i,int x,int f){
if(i == 0) return;
if(chk(v[i] , x) == f) {ans = i;return Query(ch[i][f^1],x,f);}
else return Query(ch[i][f],x,f);
}
}
using namespace Treap;
int main(){
scanf("%d",&m);
while( m-- ){
scanf("%d%d",&flag,&x);
switch(flag){
case 1: insert(root,x);break;
case 2: remove(root,x);break;
case 3: printf("%d\n",Qrank(root,x));break;
case 4: printf("%d\n",order(root,x));break;
case 5: ans = 0;Query(root,x,0);printf("%d\n",v[ans]);break;
case 6: ans = 0;Query(root,x,1);printf("%d\n",v[ans]);break;
default: puts(">.< !");break;
}
}
return 0;
}