splay 模板

来源:互联网 发布:c语言数组变成字符串 编辑:程序博客网 时间:2024/05/22 00:38
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn = 1000010;int sz, root;int ch[maxn][2], cnt[maxn], size[maxn], p[maxn], key[maxn];inline void clear(int x) {ch[x][0] = ch[x][1] = cnt[x] = size[x] = p[x] = key[x] = 0;}inline int get(int x) {return ch[p[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 fa = p[x], gfa = p[p[x]], which = get(x);ch[fa][which] = ch[x][which^1];p[ch[fa][which]] = fa;ch[x][which^1] = fa;p[fa] = x;p[x] = gfa;if(gfa)ch[gfa][ch[gfa][1] == fa] = x;update(fa);update(x); }inline void splay(int x) {for(int fa; fa = p[x]; rotate(x))if(p[fa])rotate((get(x) == get(fa))?fa:x);root = x;}inline void insert(int x) {int now = root, fa = 0;if(now == 0) {sz++;root = sz;key[sz] = x; ch[sz][0] = ch[sz][1] = p[sz] = 0;cnt[sz] = size[sz] = 1;return;}while(1) {if(key[now] == x) {cnt[now]++;update(now);update(fa);splay(now);return;}fa = now, now = ch[now][key[now] < x];if(now == 0) {sz++;ch[sz][0] = ch[sz][1] = 0;cnt[sz] = size[sz] = 1;p[sz] = fa;key[sz] = x;ch[fa][key[fa] < x] = sz;update(fa);splay(sz);return;}} }int find(int x) {int now = root, ans = 0;while(1) {if(x < key[now])now = ch[now][0];else {ans += (ch[now][0]?size[ch[now][0]]:0);if(x == key[now]) {splay(now);return ans+1;}ans += cnt[now];now = ch[now][1];}}}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];}}}int pre() {int now = ch[root][0];while(ch[now][1])now = ch[now][1];return now;}int next() {int now = ch[root][1];while(ch[now][0])now = ch[now][0];return now;}void del(int x) {int whatever = find(x);if(cnt[root] > 1) {cnt[root]--;update(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]; p[root] = 0;clear(oldroot);return;} else if(!ch[root][1]) {int oldroot = root;root = ch[root][0]; p[root] = 0;clear(oldroot);return;}int bigleft = pre(), oldroot = root;splay(bigleft);ch[root][1] = ch[oldroot][1];p[ch[root][1]] = root;clear(oldroot);update(root);return;}/*101 1064654 11 3177211 4609291 6449851 841851 898516 819681 4927375 493598*/int main() {int n;scanf("%d", &n);for(int i = 1; i <= n; i++) {int t, x;scanf("%d%d", &t, &x);switch(t) {case 1: insert(x); break;case 2: del(x);break;case 3: printf("%d\n", find(x)); break;case 4: printf("%d\n", findx(x)); break;case 5: insert(x); printf("%d\n", key[pre()]); del(x); break;case 6: insert(x); printf("%d\n", key[next()]); del(x); break;}}return 0;}


0 0
原创粉丝点击