路漫漫其修远兮~
手抄一枚splay树 长长的模版。。
关于spaly树的讲解 网上很多 随手贴一篇 貌似这题可以用什么bst啦 堆啦 平衡树啦 等等 这些本质都是有共同点的 查找、删除特别快 因为都有序 而且平衡~
看题很容易想到用线段树做 不过数太大了 离散化嘛 你肯定这么想 不过这题真不好离散 没想出来 只能硬啃这树那树了
用splay树存下被删除的数 为原先的第几 再根据左边有多少个节点 右边有多少个节点 与询问的数比较大小 看他具体该在哪个位置
每插入一个数 就把它旋到根节点 这样会节省时间 应该跟输入数据有关 我试了把询问时的那步旋转去掉 跑得死慢了
看代码吧 挺有意思的
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #define N 10010 7 using namespace std; 8 int n,m; 9 struct splaytree 10 { 11 int size[N],ch[N][2],f[N],va[N]; 12 int root,top; 13 inline void zig(int x) 14 { 15 int y = f[x],z = f[y]; 16 ch[y][1] = ch[x][0];f[ch[x][0]] = y; 17 f[x] = z;ch[x][0] = y;f[y] = x; 18 if(z) ch[z][ch[z][1]==y] = x; 19 pushup(y); 20 } 21 inline void zag(int x) 22 { 23 int y = f[x],z = f[y]; 24 ch[y][0] = ch[x][1];f[ch[x][1]] = y; 25 ch[x][1] = y;f[y] = x;f[x] = z; 26 if(z) ch[z][ch[z][1]==y] = x; 27 pushup(y); 28 } 29 inline void zigzig(int x) 30 { 31 int y = f[x],z = f[y],fz = f[z]; 32 ch[z][1] = ch[y][0]; f[ch[y][0]] = z; 33 ch[y][1] = ch[x][0]; f[ch[x][0]] = y; 34 f[z] = y;ch[y][0] = z; 35 f[y] = x;ch[x][0] = y; 36 f[x] = fz; 37 if(fz) ch[fz][ch[fz][1]==z] = x; 38 pushup(z);pushup(y); 39 } 40 inline void zagzag(int x){ 41 42 int y=f[x], z=f[y], fz=f[z]; 43 44 ch[z][0]=ch[y][1]; f[ch[y][1]]=z; 45 46 ch[y][0]=ch[x][1]; f[ch[x][1]]=y; 47 48 f[z] = y;ch[y][1] = z; 49 f[y] = x;ch[x][1] = y; 50 f[x] = fz; 51 if(fz) ch[fz][ch[fz][1]==z] = x; 52 pushup(z);pushup(y); 53 } 54 inline void zigzag(int x) 55 { 56 int y = f[x],z = f[y],fz = f[z]; 57 ch[y][1] = ch[x][0] ; f[ch[x][0]] = y; 58 ch[z][0] = ch[x][1] ; f[ch[x][1]] = z; 59 f[z] = x;ch[x][0] = y; 60 f[y] = x;ch[x][1] = z; 61 f[x] = fz; 62 if(fz) ch[fz][ch[fz][1]==z] = x; 63 pushup(y);pushup(z); 64 } 65 inline void zagzig(int x) 66 { 67 int y = f[x],z = f[y],fz = f[z]; 68 ch[y][0] = ch[x][1] ; f[ch[x][1]] = y; 69 ch[z][1] = ch[x][0] ; f[ch[x][0]] = z; 70 f[z] = x;ch[x][0] = z; 71 f[y] = x;ch[x][1] = y; 72 f[x] = fz; 73 if(fz) ch[fz][ch[fz][1]==z] = x; 74 pushup(y);pushup(z); 75 } 76 void splay(int x,int goal) 77 { 78 int y,z; 79 while(f[x]!=goal) 80 { 81 if(f[f[x]]==goal) 82 { 83 y = f[x]; 84 if(ch[y][1]==x) 85 zig(x); 86 else 87 zag(x); 88 } 89 else 90 { 91 y = f[x];z =f[y]; 92 if(ch[z][1]==y) 93 { 94 if(ch[y][1]==x) 95 zigzig(x); 96 else 97 zagzig(x); 98 } 99 else 100 { 101 if(ch[y][0]==x) 102 zagzag(x); 103 else 104 zigzag(x); 105 } 106 } 107 } 108 pushup(x); 109 if(f[x]==0) 110 root = x; 111 } 112 inline void pushup(int x) 113 { 114 size[x] = size[ch[x][0]]+size[ch[x][1]]+1; 115 } 116 void init() 117 { 118 size[0] = ch[0][1] = ch[0][0] = f[0] = root = va[0] = top = 0; 119 insert(1000000001); 120 } 121 inline int newnode(int v) 122 { 123 size[++top] = 1; 124 ch[top][0] = ch[top][1] = f[top] = 0; 125 va[top] = v; 126 return top; 127 } 128 void insert(int v) 129 { 130 int r = root,x; 131 for(;;) 132 { 133 if(v>=va[r]) 134 { 135 if(ch[r][1]) 136 r = ch[r][1]; 137 else 138 { 139 x = newnode(v); 140 ch[r][1] = x; 141 f[x] = r; 142 break; 143 } 144 } 145 else 146 { 147 if(ch[r][0]) 148 r = ch[r][0]; 149 else 150 { 151 x = newnode(v); 152 ch[r][0] = x; 153 f[x] = r; 154 break; 155 } 156 } 157 } 158 splay(x,0); 159 } 160 int query(int v) 161 { 162 int r = root,k = v,res = size[ch[root][0]]; 163 for(;;) 164 { 165 if(k<va[r]-res) 166 { 167 if(ch[r][0]) 168 { 169 r = ch[r][0]; 170 res -= size[ch[r][1]]+1; 171 } 172 else 173 { 174 splay(r,0); 175 return k+res; 176 } 177 } 178 else 179 { 180 if(ch[r][1]) 181 { 182 r = ch[r][1]; 183 res += 1+size[ch[r][0]]; 184 } 185 else 186 { 187 splay(r,0); 188 return k+res+1; 189 } 190 } 191 } 192 } 193 }tree; 194 int main() 195 { 196 int k; 197 char s[5]; 198 tree.init(); 199 scanf("%d%d",&n,&m); 200 while(m--) 201 { 202 scanf("%s%d",s,&k); 203 if(s[0]=='L') 204 printf("%d\n",tree.query(k)); 205 else 206 { 207 int x = tree.query(k); 208 tree.insert(x); 209 } 210 } 211 return 0; 212 }