BZOJ-3595 方伯伯的OJ 双Treap

7 篇文章 0 订阅
5 篇文章 0 订阅

大家都很强, 可与之共勉。

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;  
        }
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值