求助,奇怪的splay问题
查看原帖
求助,奇怪的splay问题
1036693
carp_oier楼主2023/10/12 17:56
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rl register ll
#define ws putchar(' ')
#define wl putchar('\n')

template <class T> inline void read(T &res)
{
    char ch = getchar(); bool f = 0; res = 0;
    for(; !isdigit(ch); ch = getchar()) f |= ch == '-'; 
    for(; isdigit(ch); ch = getchar()) res = (res << 1) + (res << 3) + (ch ^ 48); 
    res = f ? ~res + 1 : res; 
}

template <class T> inline void waw(T x)
{
    if(x > 9) waw(x / 10); 
    putchar(x % 10 + '0'); 
}

template <class T> inline void ww(T x)
{
    if(x < 0) x = ~x + 1, putchar('-'); 
    waw(x); 
}

const ll N = 2e5 + 10, INF = 1e16;

ll n, m, root, idx, w[N];

struct tree
{
    ll s[2], fa, size, key;
    inline void init(ll v, ll p)
    {
        key = v, fa = p, size = 1, s[0] = s[1] = 0;
    }
}tr[N];

#define fa(x) tr[(x)].fa
#define ls(x) tr[(x)].s[0]
#define rs(x) tr[(x)].s[1]

inline bool get(ll x) { return x == rs(fa(x)); }
inline void pushup(ll u) { tr[u].size = tr[ls(u)].size + tr[rs(u)].size +  1; }

inline void rotate(ll x)
{
    ll y = fa(x), z = fa(y); bool c = get(x);
    fa(tr[x].s[c ^ 1]) = y, tr[y].s[c] = tr[x].s[c ^ 1];
    tr[x].s[c ^ 1] = y, fa(y) = x, fa(x) = z;
    if(z) tr[z].s[y == rs(z)] = x;
    pushup(y), pushup(x);
}

inline void splay(ll x, ll y)
{
    for(rl f = fa(x); f = fa(x), f != y; rotate(x))
        if(fa(f) != y) rotate(get(f) == get(x) ? f : x);
    if(!y) root = x;
}

inline ll build(ll l, ll r, ll p)
{
    ll mid = l + r >> 1, u = ++ idx;
    tr[u].init(w[mid], p);
    if(l < mid) ls(u) = build(l, mid - 1, u);
    if(mid < r) rs(u) = build(mid + 1, r, u);
    pushup(u); return u;
}

inline ll kth(ll rk)
{
    ll now = root; 
    while(now)
    {
        ll sz = tr[ls(now)].size + 1;
        if(sz > rk) now = ls(now);
        else if(sz == rk) return now;
        else rk -= sz, now = rs(now);
    }
    return -1;
}

inline ll rnk(ll key)
{
    ll res = 1, now = root, p;
    while(now)
        if(p = now, tr[now].key < key) res += tr[ls(now)].size + 1, now = rs(now);
        else now = ls(now);
    return splay(p, 0), res;
}

inline void remove(ll key)
{
    ll rk = rnk(key), l = kth(rk - 1), r = kth(rk + 1);
    splay(l, 0), splay(r, l);
    ls (r) = 0; pushup(r), pushup(l);
}

inline void top()
{
    ll s; read(s); remove(s);
    ll l = kth(1), r = kth(2); // 1 是哨兵 2 是原先的第一个点
        // ww(l), ws, ww(r), wl;
    splay(l, 0), splay(r, l);
    ll u = ++ idx; tr[u].init(s, r);
    ls(r) = u; pushup(r), pushup(l);
}

inline void bottom()
{
    ll s, sz = tr[root].size - 1; read(s); remove(s);
    ll l = kth(sz), r = kth(sz + 1);
    splay(l, 0), splay(r, l);
    ll u = ++ idx; tr[u].init(s, r);
    ls(r) = u; pushup(r), pushup(l);
}

inline void insert()
{
    ll s, t; read(s), read(t);
    ll x = rnk(s); remove(s);
    ll l = kth(x + t + 1), r = kth(x + t + 2);
    splay(l, 0), splay(r, l);
    ll u = ++ idx; tr[u].init(s, r), ls(r) = u;
    pushup(r), pushup(l);
}

inline void ask()
{
    ll s; read(s);
    ll x = rnk(s) - 1;
    ww(x), wl;
}

inline void query()
{
    ll s; read(s);
    ll x = kth(s);
    ww(x), wl;
}

inline void print(ll u)
{
    if(ls(u)) print(ls(u));
    if(tr[u].key) printf("u : %lld key : %lld \n", u, tr[u].key);
    if(rs(u)) print(rs(u));
}

int main()
{
    freopen("1.in", "r", stdin), freopen("1.out", "w", stdout);

    read(n), read(m);

    for(rl i=1; i <= n; ++ i) read(w[i]);

    w[0] = w[n + 1] = -INF;

    root = build(0, n + 1, 0);

    while(m -- )
    {
        // ww(m), wl;
        string str; cin >> str;

        switch(str[0])
        {   
            case 'T' : top(); break;
            case 'B' : bottom(); break;
            case 'I' : insert(); break;
            case 'A' : ask(); break;
            case 'Q' : query(); break;
        }
        // print(root), wl;
    }
    return 0;
}
2023/10/12 17:56
加载中...