BZOJ-3595 方伯伯的OJ 双Treap
2017-05-30 10:49
369 查看
大家都很强, 可与之共勉。
2017年的Rank6/************************************************************** Problem: 3595 User: Lazer2001 Language: C++ Result: Accepted Time:2252 ms Memory:16952 kb ****************************************************************/ #include <cctype> #include <cstdio> namespace FastIO { const size_t str = 1 << 20; struct Reader { char buf[str], *s, *t; Reader ( ) : s( ), t( ), buf() { } inline char pick ( ) { return (s == t) ? ( t = buf + fread ( s = buf, 1, str , stdin ), *s++ ) : ( *s++ ); } template < class T > inline Reader& operator >> ( T& x ) { static char ch; static short opt; opt = (ch != 45); while ( !isdigit ( ch = pick () ) && (ch ^ -1) && ( ch ^ 45 ) ); if ( ch == -1 ) return *this; if ( ch == 45 ) { opt = 0; ch = pick (); } for ( x = -48 + ch; isdigit ( ch = pick () ); ( x *= 10 ) += ch - 48 ); opt ? 1 : x = -x; return *this; } } cin; struct Writer { char buf[str], *s, *t; Writer () : s ( buf ), t( buf + str ), buf ( ) { } ~Writer () { fwrite( buf, 1, s - buf, stdout ); } inline void echo ( char c ) { ( s == t ) ? ( fwrite ( s = buf, 1, str, stdout ), *s++ = c ) : ( *s++ = c ); } inline Writer& operator << ( long long x ) { if( !x ) return echo( 48 ), *this; static int t[21], top; while ( x ) t[++top] = x % 10, x /= 10; while ( top ) echo(t[top--] + 48); return *this; } inline Writer& operator << (const char* s) { while ( *s ) echo( *s++ ) ; return *this; } } cout; const char *endl = "\n"; } using FastIO :: cin; using FastIO :: cout; using FastIO :: endl; inline int rand ( ) { static int seed = 233; return seed = ( int ) seed * 482711LL % 2147483647; } const int Inf = 0x3f3f3f3f; int cnt = 1, tot = 1; class Treap{ public: struct node{ node *lc, *rc; int s, id, r, L, R; }t[300055], *null, *root; inline void init() { null = &t[0]; null -> lc = null -> rc = 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 = 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); } inline 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); } inline 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); } inline 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); 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); } inline 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); } inline 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; struct Map { struct node { node *lc, *rc; int r, id, rank; }t[300055], *null, *root; inline void init() { null = &t[0]; null -> lc = null -> rc = null; null -> rank = null -> r = -Inf; root = null; } inline node *NewNode(int index, int rank) { t[tot].lc = t[tot].rc = null; t[tot].r = rand(); t[tot].id = index; t[tot].rank = rank; return &t[tot++]; } inline void maintain(node *&p) { if(p->lc->r > p->r) { node *temp = p -> lc; p -> lc = temp -> rc; temp -> rc = p; p = temp; } else if(p->rc->r > p->r) { node *temp = p -> rc; p -> rc = temp -> lc; temp -> lc = p; p = temp; } } inline void insert(node *&p, int index, int rank) { if(p == null) { p = NewNode(index, rank); return; } if(index == p -> id) p -> rank = rank; else if(index < p -> id) insert(p -> lc, index, rank); else insert(p -> rc, index, rank); maintain(p); } inline int find(node *&p, int index) { if(p == null) return 0; if(p -> id == index) return p -> rank; if(p -> id > index) return find(p -> lc, index); return find(p -> rc, index); } inline void remove(node *&p, int index) { if(p == null) return; if(p -> id == index) p -> rank = 0; else if(p -> id > index) remove(p -> lc, index); else remove(p -> rc, index); } } m; int main() { register int N, M; t.init(); m.init(); cin >> N; t.insert(t.root, 1, N, 1); int mmin = 0, mmax = N, a = 0; for ( cin >> M; M; --M ) { static int sign, x, pos; cin >> sign >> x; x -= a; if(sign == 1) { static int y; cin >> y; y -= a; pos = m.find(m.root, x); if(!pos) pos = x; a = t.getrank(t.root, pos); cout << a << endl; t.del(t.root, pos); t.insert(t.root, pos, pos, y); m.remove(m.root, x); m.insert(m.root, y, pos); } else if(sign == 2) { pos = m.find(m.root, x); if(!pos) pos = x; a = t.getrank(t.root, pos); cout << a << endl; t.del(t.root, pos); m.insert(m.root, x, pos = --mmin); t.insert(t.root, pos, pos, x); } else if(sign == 3) { pos = m.find(m.root, x); if(!pos) pos = x; a = t.getrank(t.root, pos); cout << a << endl; t.del(t.root, pos); m.insert(m.root, x, pos = ++mmax); t.insert(t.root, pos, pos, x); } else { a = t.getindex(t.root, x); cout << a << endl; } } }
相关文章推荐
- 【Treap】[Scoi2014] bzoj3595 方伯伯的Oj
- BZOJ 3595: [Scoi2014]方伯伯的Oj SBT+可持久化Treap
- 【双Treap】[Scoi2014] bzoj3595 方伯伯的Oj
- 【bzoj 3595】: [Scoi2014]方伯伯的Oj
- [BZOJ3595][SCOI2014]方伯伯的OJ(平衡树)
- 【bzoj 3595】: [Scoi2014]方伯伯的Oj
- [SCOI2014]方伯伯的OJ (非旋treap不可做! (╯‵□′)╯︵┻━┻)
- 无旋treap:从单点到区间(例题 BZOJ1500&NOI2005 维护数列 )
- bzoj 3598 [Scoi2014]方伯伯的商场之旅 数位dp
- bzoj1503 treap
- bzoj1691 treap
- [bzoj3527]&[caioj1451][FFT]多项式
- bzoj3594 [Scoi2014]方伯伯的玉米田
- BZOJ 1503 郁闷的出纳员 treap
- bzoj 3598: [Scoi2014]方伯伯的商场之旅【数位dp】
- BZOJ[1208][HNOI2004]宠物收养所 Treap
- BZOJ3224[Tyvj 1728 普通平衡树]题解--Treap
- bzoj3224Tyvj 1728 普通平衡树 treap
- bzoj1588[HNOI2002]营业额统计 treap
- 【Treap/非旋转Treap】BZOJ3224 [Tyvj1728]普通平衡树