【Treap】[Scoi2014] bzoj3595 方伯伯的Oj
2015-03-12 13:52
393 查看
题目点这里
cena卡STL。。所以双treap见:http://blog.csdn.net/qq_21841245/article/details/44977711。。
这道题见证了什么叫做一时手贱千古恨 :) 强制在线的离散化 想写对拍都不容易orz用了各种乱七八糟的查错方法终于知道错哪了!!!
orz交了bzoj拿了rank3 指针写比鲲哥快哈哈哈哈 当心理安慰吧 = =。。纪念我被这道题挫伤的小心脏啊。。。
这题维护序列。。用splay挺好的 treap也行直接把它的“排名”当做排序关键字就行了(提到前面的就是负的 其实这是鲲哥的思路 orz)
然后开个map保存每个编号对应的排序关键字 每次查找就行了 对于那些写双splay的 只能orz
因为空间开不下 所以把m[x] == 0的情况当做它的编号就是自己本身 所以千万不能用到0作为排序关键字!!!!!!!!!!千万!!!!!!
cena卡STL。。所以双treap见:http://blog.csdn.net/qq_21841245/article/details/44977711。。
这道题见证了什么叫做一时手贱千古恨 :) 强制在线的离散化 想写对拍都不容易orz用了各种乱七八糟的查错方法终于知道错哪了!!!
orz交了bzoj拿了rank3 指针写比鲲哥快哈哈哈哈 当心理安慰吧 = =。。纪念我被这道题挫伤的小心脏啊。。。
这题维护序列。。用splay挺好的 treap也行直接把它的“排名”当做排序关键字就行了(提到前面的就是负的 其实这是鲲哥的思路 orz)
然后开个map保存每个编号对应的排序关键字 每次查找就行了 对于那些写双splay的 只能orz
因为空间开不下 所以把m[x] == 0的情况当做它的编号就是自己本身 所以千万不能用到0作为排序关键字!!!!!!!!!!千万!!!!!!
#include <cstdio> #include <iostream> #include <map> #include <cstdlib> using namespace std; int read() { int n = 0, sign = 1; char c = getchar(); while(c > '9' || c < '0') {if(c == '-') sign = -1; c = getchar();} while(c >= '0' && c <= '9') {n = n*10 + c-'0'; c = getchar(); } return sign * n; } const int inf = 0x3f3f3f3f; map <int, int> m; int cnt = 1; struct treap{ struct node{ node *lc, *rc, *f; int s, id, r, L, R; }t[300055], *null, *root; inline void init() { null = &t[0]; null -> lc = null -> rc = null -> f = null; null -> s = 0; null -> id = null -> L = null -> R = null -> r = -inf; root = null; } inline node *NewNode(int index, int L, int R) { t[cnt].lc = t[cnt].rc = t[cnt].f = null; t[cnt].r = rand(); t[cnt].id = index; t[cnt].L = L; t[cnt].R = R; t[cnt].s = R - L + 1; return &t[cnt++]; } inline void pushup(node *&p){ p->s = p->lc->s + p->rc->s + (p->R-p->L+1);} inline void maintain(node *&p) { if(p->lc->r > p->r) { node *temp = p -> lc; p -> lc = temp -> rc; temp -> rc = p; pushup(p); p = temp; } else if(p->rc->r > p->r) { node *temp = p -> rc; p -> rc = temp -> lc; temp -> lc = p; pushup(p); p = temp; } pushup(p); } void insert(node *&p, int L, int R, int index) { if(p == null) { p = NewNode(index, L, R); return; } if(R < p -> L) insert(p -> lc, L, R, index); else insert(p -> rc, L, R, index); maintain(p); } void merge(node *&ne, node *p, node *q) { if(p == null || q == null) { ne = p == null ? q : p; return; } if(p->r > q->r) { ne = p; merge(ne->rc, p->rc, q); } else{ ne = q; merge(ne->lc, p, q->lc); } pushup(ne); } void del(node *&p, int pos) { if(p == null) return; if(p->L <= pos && pos <= p->R) { if(p->L == p->R) merge(p, p->lc, p->rc); // 经证实这句是错的。不过反正窝退役了不管了2333 else if(p->L == pos) { ++ p -> L; ++ p -> id; pushup(p); } else if(p->R == pos) { -- p -> R; pushup(p); } else { insert(p -> rc, pos + 1, p -> R, pos + 1); p -> R = pos - 1; pushup(p); } return; } if(p->L > pos) del(p -> lc, pos); else del(p -> rc, pos); maintain(p); } int getrank(node *p, int pos) { if(p == null) return 0; if(p->L <= pos && pos <= p->R) return (pos - p->L + 1) + p->lc->s; if(p->L > pos) return getrank(p->lc, pos); else return getrank(p->rc, pos) + p->lc->s + (p->R - p->L + 1); } int getindex(node *p, int k) { if(p == null) return 0; int lsize = p->lc->s; if(k <= lsize) return getindex(p->lc, k); if(lsize < k && lsize + (p->R - p->L + 1) >= k) { if(p->L == p->R) return p->id; else return k-lsize-1 + p->L; } else return getindex(p->rc, k - lsize - (p->R - p->L + 1)); } }t; int N, M; int main() { srand(20150233); t.init(); N = read(); t.insert(t.root, 1, N, 1); int mmin = 0, mmax = N, a = 0; for(M = read(); M--; ) { int sign = read(), x = read(); x -= a; if(sign == 1) { int y = read(); y -= a; int pos = m[x]; if(!pos) pos = x; printf("%d\n", a = t.getrank(t.root, pos)); t.del(t.root, pos); t.insert(t.root, pos, pos, y); m[x] = 0; m[y] = pos; } else if(sign == 2) { int pos = m[x]; if(!pos) pos = x; printf("%d\n", a = t.getrank(t.root, pos)); t.del(t.root, pos); m[x] = pos = --mmin; t.insert(t.root, pos, pos, x); } else if(sign == 3) { int pos = m[x]; if(!pos) pos = x; printf("%d\n", a = t.getrank(t.root, pos)); t.del(t.root, pos); m[x] = pos = ++mmax; t.insert(t.root, pos, pos, x); } else printf("%d\n", a = t.getindex(t.root, x)); } return 0; }
相关文章推荐
- BZOJ 3595: [Scoi2014]方伯伯的Oj SBT+可持久化Treap
- 【双Treap】[Scoi2014] bzoj3595 方伯伯的Oj
- 【bzoj 3595】: [Scoi2014]方伯伯的Oj
- [BZOJ3595][SCOI2014]方伯伯的OJ(平衡树)
- 【bzoj 3595】: [Scoi2014]方伯伯的Oj
- [SCOI2014]方伯伯的OJ (非旋treap不可做! (╯‵□′)╯︵┻━┻)
- BZOJ-3595 方伯伯的OJ 双Treap
- BZOJ3598[Scoi2014]方伯伯的商场之旅 数位DP
- bzoj 3597: [Scoi2014]方伯伯运椰子 0/1分数规划
- [BZOJ]3597: [Scoi2014]方伯伯运椰子 01分数规划+spfa
- BZOJ3598 [Scoi2014]方伯伯的商场之旅
- 【bzoj3594】 SCOI2014方伯伯的玉米田 dp+二维树状数组优化
- [BZOJ3594] [Scoi2014]方伯伯的玉米田
- BZOJ 3594 [SCOI 2014] 方伯伯的玉米田 (DP,树状数组优化)
- 【BZOJ3598】【SCOI2014】方伯伯的商场之旅
- 【bzoj3594】【SCOI2014】【方伯伯的玉米田】【dp+二维树状数组】
- SCOI2014 方伯伯的OJ onlinejudge
- BZOJ3594: [Scoi2014]方伯伯的玉米田
- bzoj3598 [Scoi2014]方伯伯的商场之旅
- [BZOJ3598][SCOI2014]方伯伯的商场之旅(数位DP,记忆化搜索)