Splay初步【bzoj1503】
2015-12-04 12:40
309 查看
做了一道水题,把bzoj1503用Splay重新写了一下。
View Code
#include <bits/stdc++.h> #define rep(i, a, b) for (int i = a; i <= b; i++) #define REP(i, a, b) for (int i = a; i < b; i++) #define drep(i, a, b) for (int i = a; i >= b; i--) #define mp make_pair #define pb push_back #define clr(x) memset(x, 0, sizeof(x)) #define xx first #define yy second using namespace std; typedef long long i64; typedef pair<int, int> pii; const int inf = ~0U >> 1; const i64 INF = ~0ULL >> 1; //*************************** struct node { node *pre, *s[2]; int key, size, mul; node() { pre = s[0] = s[1] = 0; size = mul = 1; } node(int _key) :key(_key) { pre = s[0] = s[1] = 0; size = mul = 1; } bool getlr() { return pre->s[1] == this; } node *link(int w, node *p) { s[w] = p; if (p) p->pre = this; return this; } void update() { size = mul + (s[0] ? s[0]->size : 0) + (s[1] ? s[1]->size : 0); } } *root; void rot(node* p) { node *q = p->pre->pre; p->getlr() ? p->link(0, p->pre->link(1, p->s[0])) : p->link(1, p->pre->link(0, p->s[1])); p->pre->update(); if (q) q->link(q->s[1] == p->pre, p); else { p->pre = 0; root = p; } } void splay(node *p, node *tar) { while (p->pre != tar && p->pre->pre != tar) p->getlr() == p->pre->getlr() ? (rot(p->pre), rot(p)) : (rot(p), rot(p)); if (p->pre) rot(p); p->update(); } void insrt(int k) { node *p = root, *q = NULL; while (p) { q = p; if (k > p->key) p = p->s[1]; else if (k < p->key) p = p->s[0]; else break; } if (!p) {p = new node(k); if (!q) { root = p; return; } q->link(q->key < k, p); q->update(); splay(p, 0); } else { p->mul++; splay(p, 0); } } node *findkth(int x) { node *p = root; node *t; while (1) { int w = (p->s[0] ? p->s[0]->size : 0); if (x <= w) t = p->s[0]; else if (x > w + p->mul) { x -= w + p->mul; t = p->s[1]; } else break; p = t; } splay(p, 0); return p; } node *find(node *p, int x) { if (p->key < x) return find(p->s[1], x); else if (p->key > x) return find(p->s[0], x); else return p; } int main() { int ori(0); int n, m; scanf("%d%d", &n, &m); int tot(0); char op[5]; int x; while (n--) { scanf("%s%d", op, &x); if (op[0] == 'I') { if (x >= m) { ori++; insrt(x - tot); } } else if (op[0] == 'A') tot += x; else if (op[0] == 'S') { tot -= x; insrt(m - tot - 1); splay(find(root, m - tot - 1), 0); root = root->s[1]; if (root) root->pre = 0; } else if (op[0] == 'F') { if (!root || x > root->size) puts("-1"); else printf("%d\n", findkth(root->size - x + 1)->key + tot); } } printf("%d\n", ori - (root ? root->size : 0)); return 0; }
View Code
相关文章推荐
- iOS常用手势识别器
- 在用户空间发生中断时,上下文切换的过程
- XML解析
- RS-485总线前世今生;
- Spring security安全认证框架
- com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)
- java 深入技术四(Set)
- weblogic启动 web应用ssh关闭 nohup命令
- hdu 5585 Numbers【大数+同余定理】
- Valid Number
- Treap初步
- DrawSVG - SVG 路径动画 jQuery 插件
- HTML5新特性总结
- 使用开源项目Asynchttpclient的GET_POST访问网络,上传文件
- 南大软院大神养成计划第十九天
- 【网络编程基础】Linux下进程通信方式(共享内存,管道,消息队列,Socket)
- mongodump & mongorestore
- java统计中文字符出现次数
- java 试题java编译问题
- 读取文件夹下的文件列表