模板题一枚
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <queue> #include <algorithm> #include <vector> #include <cstring> #include <stack> #include <cctype> #include <utility> #include <map> #include <string> #include <climits> #include <set> #include <string> #include <sstream> #include <utility> #include <ctime> using std::priority_queue; using std::vector; using std::swap; using std::stack; using std::sort; using std::max; using std::min; using std::pair; using std::map; using std::string; using std::cin; using std::cout; using std::set; using std::queue; using std::string; using std::istringstream; using std::make_pair; using std::getline; using std::greater; using std::endl; using std::multimap; using std::deque; typedef long long LL; typedef unsigned long long ULL; typedef pair<int, int> PAIR; typedef multimap<int, int> MMAP; const int MAXN(80010); const int MAXM(10010); const int MAXE(10010); const int SIGMA_SIZE(26); const int MAXH(19); const int INFI(2000000000); const int MOD(1000000007); const ULL BASE(31); const LL LIM(10000000); const int INV(-10000); struct NODE { int num, size; //s1表示区域正数的个数 NODE *fa, *ch[2]; }; NODE *point[MAXN]; int arr[MAXN]; struct SPLAY_TREE { NODE pool[MAXN]; NODE *root, *NIL, *rear; inline void push_up(NODE *sour) { sour->size = sour->ch[0]->size+sour->ch[1]->size+1; } void initNIL() { NIL->ch[0] = NIL->ch[1] = NIL->fa = NIL; NIL->num = NIL->size = 0; } void build(NODE *&sour, NODE *tf, int l, int r) { if(l > r) return; int m = (l+r) >> 1; newnode(sour, tf, arr[m]); point[arr[m]] = sour; build(sour->ch[0], sour, l, m-1); build(sour->ch[1], sour, m+1, r); push_up(sour); } void init(int n) { NIL = pool; initNIL(); rear = pool+1; newnode(root, NIL, 0); //插入无穷小 newnode(root->ch[1], root, 0); //插入无穷大 build(root->ch[1]->ch[0], root->ch[1], 1, n); //建树 push_up(root->ch[1]); push_up(root); } void newnode(NODE *&sour, NODE *f, int num) { sour = rear++; sour->num = num; sour->size = 1; sour->fa = f; sour->ch[0] = sour->ch[1] = NIL; } void rotate(NODE *sour, int flag) { NODE *f = sour->fa; // push_down(f); // push_down(sour); f->ch[!flag] = sour->ch[flag]; sour->ch[flag]->fa = f; sour->fa = f->fa; if(f->fa != NIL) f->fa->ch[f->fa->ch[1] == f] = sour; sour->ch[flag] = f; f->fa = sour; push_up(f); } void splay(NODE *sour, NODE *goal) { // push_down(sour); while(sour->fa != goal) { if(sour->fa->fa == goal) rotate(sour, sour->fa->ch[0] == sour); else { NODE *f = sour->fa; int flag = (f->fa->ch[0] == f); if(f->ch[flag] == sour) rotate(sour, !flag); else rotate(f, flag); rotate(sour, flag); } } push_up(sour); if(goal == NIL) root = sour; } NODE *select(NODE *sour, int r) { while(sour != NIL) { // push_down(sour); if(r == sour->ch[0]->size+1) break; if(r <= sour->ch[0]->size) sour = sour->ch[0]; else { r -= sour->ch[0]->size+1; sour = sour->ch[1]; } } return sour; } void divide(NODE *sour) { NODE *tp1, *tp2; splay(sour, NIL); tp1 = select(root->ch[0], root->ch[0]->size); tp2 = select(root->ch[1], 1); splay(tp1, NIL); splay(tp2, root); tp2->ch[0] = NIL; push_up(root->ch[1]); push_up(root); } void TOP(int op) { divide(point[op]); NODE *tp; tp = select(root, 1); splay(tp, NIL); tp = select(root, 2); splay(tp, root); tp->ch[0] = point[op]; point[op]->fa = tp; push_up(root->ch[1]); push_up(root); } void BOTTOM(int op) { divide(point[op]); NODE *tp; tp = select(root, root->size-1); splay(tp, NIL); tp = select(root, root->size); splay(tp, root); tp->ch[0] = point[op]; point[op]->fa = tp; push_up(root->ch[1]); push_up(root); } void INSERT(int op, int T) { splay(point[op], NIL); int temp = root->ch[0]->size; divide(point[op]); NODE *tp = select(root, temp+T); splay(tp, NIL); tp = select(root, temp+1+T); splay(tp, root); tp->ch[0] = point[op]; point[op]->fa = tp; push_up(root->ch[1]); push_up(root); } int ASK(int op) { splay(point[op], NIL); return root->ch[0]->size-1; } int QUERY(int op) { NODE *tp = select(root, op+1); splay(tp, NIL); return root->num; } }; SPLAY_TREE spt; char str[15]; int op1, op2; int main() { int n, m; while(~scanf("%d%d", &n, &m)) { for(int i = 1; i <= n; ++i) scanf("%d", arr+i); spt.init(n); for(int i = 0; i < m; ++i) { scanf("%s%d", str, &op1); if(str[0] == 'T') spt.TOP(op1); else if(str[0] == 'B') spt.BOTTOM(op1); else if(str[0] == 'I') scanf("%d", &op2), spt.INSERT(op1, op2); else if(str[0] == 'A') printf("%d\n", spt.ASK(op1)); else printf("%d\n", spt.QUERY(op1)); } } return 0; }