您的位置:首页 > 其它

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;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: