要實現的操作是插入,刪除,找到比指定值大的,小的值操作。
splay的刪除操作可以是直接用二叉搜尋樹的刪除方式,或者是先將要刪除的節點splay到根,然後找到左子樹中最大的節點,將其splay到根的左兒子位置,此時這個節點必然是沒有右子樹的,然後直接把他當做根就好。
找大的值可以先找到如果要插入這個值會插在**,然後不執行操作,直接找前驅或者後繼就可以了。
**能力捉急,寫了整整一天,各種debug蛋疼啊= =
#include #include #include #include using namespace std;const int maxn = 2e6 + 10;
const int mod = 1000000;
const int pet = 0;
const int human = 1;
const int empty = -1;
const int inf = int_max / 3;
int ch[maxn][2], fa[maxn], val[maxn], sz, root;
void rotate(int x, int d)
ch[x][d] = y;
fa[x] = fa[y];
fa[y] = x;
}int newnode(int &r, int father, int v)
void splay(int x, int goal)
int z = fa[y], d1 = val[y] > val[z];
if (d == d1)
else
} if (goal == 0)
}void debug(int root)
int insert(int v)
int u = root;
while (ch[u][v > val[u]] != 0)
u = ch[u][v > val[u]];
int r = newnode(ch[u][v > val[u]], u, v);
splay(r, 0);
return r;
}//找後繼
int findnext(int x)
//往上尋找
int u = x;
while (fa[u] != 0 && u != ch[fa[u]][0]) u = fa[u];
return fa[u];
}//用二叉搜尋樹刪除節點的方式來刪除節點
void remove(int x)
else if (ch[x][0] == 0)
else ch[fa[x]][x == ch[fa[x]][1]] = ch[x][1];
fa[ch[x][1]] = fa[x];
} else if (ch[x][1] == 0)
else ch[fa[x]][x == ch[fa[x]][1]] = ch[x][0];
fa[ch[x][0]] = fa[x];
} else
}//先splay到根然後刪除
void remove_root()
else
//debug(root);
}int findvalminnext(int v)
int findvalmaxnext(int v)
int main()
else if (state == cmd) insert(st);
else
else
if (root == 0) state = empty;
}} printf("%d\n", ans);
} return 0;
}
BZOJ 1208, 寵物收養所
傳送門 編寫乙個支援插入 刪除元素,查詢數列中最接近某值的元素的資料結構。保證沒有重複元素存在出現在樹中。treap和splay都可做。splay苦手選擇treap,然而寫得奇醜無比。查詢最接近某值的元素可以將該值插入樹中查詢前驅與後繼,後比較。查詢完以後再刪掉。include include co...
Bzoj1208 寵物收養所
最近,阿q開了一間寵物收養所。收養所提供兩種服務 收養被主人遺棄的寵物和讓新的主人領養這些寵物。每個領養者都希望領養到自己滿意的寵物,阿q根據領養者的要求通過他自己發明的乙個特殊的公式,得出該領養者希望領養的寵物的特點值a a是乙個正整數,a 2 31 而他也給每個處在收養所的寵物乙個特點值。這樣他...
Bzoj1208 寵物收養所
最近,阿q開了一間寵物收養所。收養所提供兩種服務 收養被主人遺棄的寵物和讓新的主人領養這些寵物。每個領養者都希望領養到自己滿意的寵物,阿q根據領養者的要求通過他自己發明的乙個特殊的公式,得出該領養者希望領養的寵物的特點值a a是乙個正整數,a 2 31 而他也給每個處在收養所的寵物乙個特點值。這樣他...