题意分析
Splay 模板题,理解了好半天,照猫画虎来一发。
我写的这个效率很低啊,跑了400ms。。。
代码总览
#include<bits/stdc++.h>
using namespace std;
const int nmax = 100000<<2;
int ch[nmax][2], f[nmax], cnt[nmax], key[nmax], size[nmax];
int root = 0, sz = 0;
inline void clear(int x) {
ch[x][0] = ch[x][1] = f[x] = cnt[x] = key[x] = size[x] = 0;
}
inline int get(int x) {
return ch[f[x]][1] == x;
}
inline void update(int x) {
if(x){
size[x] = cnt[x];
if(ch[x][0]) size[x] += size[ch[x][0]];
if(ch[x][1]) size[x] += size[ch[x][1]];
}
}
inline void rotate(int x) {
int old = f[x], oldf = f[old], which = get(x);
ch[old][which] = ch[x][which^1]; f[ch[old][which]] = old;
f[old] = x; ch[x][which^1] = old;
f[x] = oldf;
if(oldf) ch[oldf][ch[oldf][1] == old] = x;
update(old);update(x);
}
inline void splay(int x) {
for(int fa; fa = f[x]; rotate(x))
if(f[fa]) rotate((get(x) == get(fa))? fa:x);
root = x;
}
inline void insert(int v) {
if(root == 0) {
sz ++; ch[sz][0] = ch[sz][1] = f[sz] = 0;
key[sz] = v; cnt[sz] = 1; size[sz] = 1;
root = sz; return;
}
int now = root, fa = 0;
while(1) {
if(key[now] == v) {
cnt[now] ++; update(now); update(fa);
splay(now); break;
}
fa = now;
now = ch[now][v > key[now]];
if(now == 0) {
sz ++;
ch[sz][0] = ch[sz][1] = 0; key[sz] = v; size[sz] = 1;
cnt[sz] = 1; f[sz] = fa; ch[fa][v > key[fa]] = sz;
update(fa);
splay(sz);
break;
}
}
}
inline int find(int v) {
int ans = 0, now = root;
while(1) {
if(v < key[now]) now = ch[now][0];
else {
ans += (ch[now][0]? size[ch[now][0]]:0);
if(v == key[now]) {splay(now); return ans + 1;}
ans += cnt[now];
now = ch[now][1];
}
}
}
inline int findx(int x) {
int now = root;
while(1) {
if(ch[now][0] && x<=size[ch[now][0]]) now = ch[now][0];
else {
int temp = (ch[now][0]?size[ch[now][0]]:0) + cnt[now];
if(x <= temp) return key[now];
x -= temp; now = ch[now][1];
}
}
}
inline int pre() {
int now = ch[root][0];
while (ch[now][1]) now = ch[now][1];
return now;
}
inline int next(){
int now = ch[root][1];
while (ch[now][0]) now = ch[now][0];
return now;
}
inline void del(int x){
int whatever = find(x);
if (cnt[root]>1) {cnt[root]--;return;}
if (!ch[root][0]&&!ch[root][1]) {clear(root);root=0;return;}
if (!ch[root][0]){
int oldroot=root;root=ch[root][1];f[root]=0;clear(oldroot);return;
}
else if (!ch[root][1]){
int oldroot=root;root=ch[root][0];f[root]=0;clear(oldroot);return;
}
int leftbig=pre(),oldroot=root;
splay(leftbig);
f[ch[oldroot][1]]=root;
ch[root][1]=ch[oldroot][1];
clear(oldroot);
update(root);
return;
}
int n,opt,x;
int main(){
scanf("%d",&n);
for(int i = 0;i<n;++i){
scanf("%d %d",&opt,&x);
if(opt == 1) insert(x);
else if(opt == 2) del(x);
else if(opt == 3) printf("%d\n",find(x));
else if(opt == 4) printf("%d\n",findx(x));
else if(opt == 5) {
insert(x); printf("%d\n",key[pre()]); del(x);
}else if(opt == 6){
insert(x); printf("%d\n",key[next()]); del(x);
}
}
return 0;
}