平衡树之treap luoguP3369
今天又复习了一遍treap,这题有前驱后继排名排位添加和删除等操作。
非常好写,虽然代码颇长但逻辑性很强。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=500010; 4 struct node 5 { 6 int l,r,w,v,size,heap; 7 }t[N]; 8 int n,rt,cnt; 9 void merge(int p) 10 { 11 t[p].size=t[t[p].l].size+t[t[p].r].size+t[p].w; 12 } 13 void rturn(int &p) 14 { 15 int ls=t[p].l; 16 t[p].l=t[ls].r; 17 t[ls].r=p; 18 t[ls].size=t[p].size; 19 merge(p); 20 p=ls; 21 } 22 void lturn(int &p) 23 { 24 int rs=t[p].r; 25 t[p].r=t[rs].l; 26 t[rs].l=p; 27 t[rs].size=t[p].size; 28 merge(p); 29 p=rs; 30 } 31 void insert(int &k,int x) 32 { 33 if(!k) 34 { 35 cnt++; 36 k=cnt; 37 t[k].w=t[k].size=1; 38 t[k].v=x; 39 t[k].heap=rand(); 40 return; 41 } 42 t[k].size++; 43 if(t[k].v==x) 44 t[k].w++; 45 else 46 { 47 if(t[k].v<x) 48 { 49 insert(t[k].r,x); 50 if(t[t[k].r].heap>t[k].heap) 51 lturn(k); 52 } 53 if(t[k].v>x) 54 { 55 insert(t[k].l,x); 56 if(t[t[k].l].heap>t[k].heap) 57 rturn(k); 58 } 59 } 60 } 61 int tmp; 62 void querypre(int k,int x) 63 { 64 if(!k)return; 65 if(x>t[k].v) 66 { 67 tmp=t[k].v;querypre(t[k].r,x); 68 } 69 else querypre(t[k].l,x); 70 } 71 void querylas(int k,int x) 72 { 73 if(!k)return; 74 if(x<t[k].v) 75 { 76 tmp=t[k].v;querylas(t[k].l,x); 77 } 78 else querylas(t[k].r,x); 79 } 80 void del(int &k,int x) 81 { 82 if(!k)return; 83 if(t[k].v==x) 84 { 85 if(t[k].w>1) 86 { 87 t[k].w--;t[k].size--; 88 } 89 else if(!t[k].l||!t[k].r)k=t[k].l+t[k].r; 90 else 91 { 92 if(t[t[k].l].heap>t[t[k].r].heap) 93 { 94 rturn(k); 95 del(k,x); 96 } 97 else 98 { 99 lturn(k); 100 del(k,x); 101 } 102 } 103 } 104 else 105 { 106 t[k].size--; 107 if(x>t[k].v) 108 del(t[k].r,x); 109 else 110 del(t[k].l,x); 111 } 112 } 113 int queryrank(int k,int x) 114 { 115 if(k==0)return 0; 116 if(t[k].v==x) 117 return t[t[k].l].size+1; 118 else 119 { 120 if(x>t[k].v)return t[t[k].l].size+t[k].w+queryrank(t[k].r,x); 121 else return queryrank(t[k].l,x); 122 } 123 } 124 int querysum(int k,int x) 125 { 126 if(k==0)return 0; 127 if(x<=t[t[k].l].size)return querysum(t[k].l,x); 128 else 129 { 130 if(x>t[t[k].l].size+t[k].w)return querysum(t[k].r,x-t[t[k].l].size-t[k].w); 131 else return t[k].v; 132 } 133 } 134 int main() 135 { 136 scanf("%d",&n); 137 for(int i=1;i<=n;++i) 138 { 139 int f,x; 140 scanf("%d%d",&f,&x); 141 if(f==1)insert(rt,x); 142 else if(f==2)del(rt,x); 143 else if(f==3)printf("%d\n",queryrank(rt,x)); 144 else if(f==4)printf("%d\n",querysum(rt,x)); 145 else if(f==5){ 146 querypre(rt,x);printf("%d\n",tmp); 147 } 148 else{ 149 querylas(rt,x);printf("%d\n",tmp); 150 } 151 } 152 return 0; 153 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。