bzoj 3224 treap模板

来源:互联网 发布:杜兰特总决赛数据效率 编辑:程序博客网 时间:2024/05/17 19:59

虽然看起来很多,但是我觉得已经是能简化到最简便的写法了,主要原因是我没有缩行,因为那样不好调试......

#include<iostream>#include<cstdio>#include<string>using namespace std;int seed = 2333;int tot=1,root;int ans;int rankk(){    seed=(seed*seed + seed) % (10003);return seed;}struct node{int son[2], value, rank, size, weight;//下次设计的时候把size设计成左右儿子的和;};node tree[200000];int getsize(int num){return tree[tree[num].son[0]].size + tree[tree[num].son[0]].weight + tree[tree[num].son[1]].size + tree[tree[num].son[1]].weight;}int getallsize(int num){return tree[num].size + tree[num].weight;}void rotate(int &num, int kind){int temp = tree[num].son[kind];tree[num].son[kind] = tree[temp].son[kind ^ 1];tree[temp].son[kind ^ 1] = num;tree[num].size = getsize(num);tree[temp].size = getsize(temp);num = temp;}void insert(int &num, int value){if (num == 0){num = tot++;tree[num].value = value;tree[num].rank = rankk();tree[num].weight = 1;return;}if (value == tree[num].value){tree[num].weight++;return;}bool f = value > tree[num].value;tree[num].size++;insert(tree[num].son[f], value);if (tree[tree[num].son[f]].rank < tree[num].rank)rotate(num, f);}void deletee(int &num, int value){if (num == 0)return;if (tree[num].value == value){if (tree[num].weight > 1)tree[num].weight--;else{if (tree[num].son[0] * tree[num].son[1] == 0)num = tree[num].son[0]+tree[num].son[1];else{rotate(num, tree[tree[num].son[1]].rank < tree[tree[num].son[0]].rank);deletee(num, value);}}}else{tree[num].size--;deletee(tree[num].son[value>tree[num].value], value);}}int getrank(int num, int value){if (num == 0)return 0 ;if (tree[num].value > value)return getrank(tree[num].son[0], value);if (tree[num].value == value)return  tree[tree[num].son[0]].size + tree[tree[num].son[0]].weight + 1;if (tree[num].value<value)return tree[num].weight + tree[tree[num].son[0]].size + tree[tree[num].son[0]].weight+getrank(tree[num].son[1], value);}int getvalue(int num, int rank){if (num == 0)return 0;if (rank <=getallsize(tree[num].son[0]))return getvalue(tree[num].son[0], rank);if (rank > getallsize(tree[num].son[0]) && rank <= getallsize(tree[num].son[0]) + tree[num].weight)return tree[num].value;else{rank -= getallsize(tree[num].son[0]) + tree[num].weight;return getvalue(tree[num].son[1], rank);}}void pre(int num, int value){if (num == 0)return;if (tree[num].value < value){ans = tree[num].value;pre(tree[num].son[1], value);}elsepre(tree[num].son[0], value);}void nextt(int num, int value){if (num == 0)return;if (tree[num].value > value){ans = tree[num].value;nextt(tree[num].son[0], value);}elsenextt(tree[num].son[1], value);}int main(){int n;scanf("%d", &n);while (n--){int a, b;scanf("%d%d", &a, &b);if (a == 1)insert(root, b);if (a == 2)deletee(root, b);if (a == 3)printf("%d\n", getrank(root, b));if (a == 4)printf("%d\n", getvalue(root, b));if (a == 5){pre(root, b);printf("%d\n", ans);}if (a == 6){nextt(root, b);printf("%d\n", ans);
                }}return 0;}