MnZn刚学Treap,人已经被旋转转傻了QAQ
查看原帖
MnZn刚学Treap,人已经被旋转转傻了QAQ
134519
qwq自动机楼主2021/8/17 21:16

RT,AC #1 #11,其他都WA,样例过了/kk

写的是旋转treap,有dalao可以帮我调一调吗qwq真的调不出来了o(╥﹏╥)o

Code:

#include <iostream>

const int MAXN = 100010;
const int INF = 2147483647;
struct node
{
    int val, rnk;
    int size, cnt;
    int son[2];
} treap[MAXN];
int tot, root;
inline int rand() // 生成随机数
{
    static unsigned _seed = 3236254;
    return _seed = (_seed * 24551 + 5371504) % 2147483648;
}
inline void pushup(int cur) { treap[cur].size = treap[treap[cur].son[0]].size + treap[treap[cur].son[1]].size + treap[cur].cnt; }
inline void rotate(int &cur, int d)
{
    int tmp = treap[cur].son[d ^ 1];
    treap[cur].son[d ^ 1] = treap[cur].son[d];
    treap[cur].son[d] = cur;
    cur = tmp;
}
void insert(int &cur, int val)
{
    if (!cur)
    {
        cur = ++tot;
        treap[cur].size = treap[cur].cnt = 1;
        treap[cur].val = val;
        treap[cur].rnk = rand();
        pushup(cur);
        return;
    }
    if (treap[cur].val == val)
    {
        treap[cur].cnt++;
        pushup(cur);
        return;
    }
    int d = val > treap[cur].val ? 1 : 0;
    insert(treap[cur].son[d], val);
    if (treap[cur].rnk < treap[treap[cur].son[d]].rnk)
        rotate(cur, d ^ 1);
    pushup(cur);
}
void remove(int &cur, int val)
{
    if (!cur)
        return;
    if (val == treap[cur].val)
    {
        if (treap[cur].son[0] && treap[cur].son[1]) // both subtree
        {
            int d = treap[treap[cur].son[0]].rnk > treap[treap[cur].son[1]].rnk ? 1 : 0;
            rotate(cur, d);
            remove(treap[cur].son[d], val);
        }
        else if (treap[cur].son[0]) // only left
        {
            rotate(cur, 1);
            remove(treap[cur].son[1], val);
        }
        else if (treap[cur].son[1]) // only right
        {
            rotate(cur, 0);
            remove(treap[cur].son[0], val);
        }
        else // no subtree
        {
            treap[cur].cnt--;
            pushup(cur);
            if (!treap[cur].cnt)
                cur = 0;
        }
    }
    else
    {
        int d = val > treap[cur].val ? 1 : 0;
        remove(treap[cur].son[d], val);
    }
    pushup(cur);
}
int getRank(int cur, int val)
{
    if (!cur)
        return 0;
    if (treap[cur].val == val)
        return treap[treap[cur].son[0]].size;
    if (treap[cur].val < val)
        return treap[treap[cur].son[0]].size + treap[cur].cnt + getRank(treap[cur].son[1], val);
    else
        return getRank(treap[cur].son[0], val);
}
int getVal(int cur, int rank)
{
    if (!cur)
        return 0;
    if (treap[treap[cur].son[0]].size >= rank)
        return getVal(treap[cur].son[0], rank);
    else if (treap[treap[cur].son[0]].size + treap[cur].cnt < rank)
        return getVal(treap[cur].son[1], rank - treap[cur].cnt - treap[treap[cur].son[0]].size);
    else
        return treap[cur].val;
}
int getPrev(int cur, int val)
{
    if (!cur)
        return -INF;
    if (treap[cur].val < val)
        return std::max(treap[cur].val, getPrev(treap[cur].son[1], val));
    else
        return getPrev(treap[cur].son[0], val);
}
int getNext(int cur, int val)
{
    if (!cur)
        return INF;
    if (treap[cur].val > val)
        return std::min(treap[cur].val, getNext(treap[cur].son[0], val));
    else
        return getNext(treap[cur].son[1], val);
}
inline void build()
{
    tot = 0;
    root = 0;
    pushup(root);
}
int main()
{
    // freopen("P3369_2.in", "r", stdin);
    // freopen("P3369_2.ans", "w", stdout);
    build();
    int n;
    std::cin >> n;
    for (int i = 1; i <= n; i++)
    {
        int op, val;
        std::cin >> op >> val;
        switch (op)
        {
        case 1:
            insert(root, val);
            break;
        case 2:
            remove(root, val);
            break;
        case 3:
            std::cout << getRank(root, val) + 1 << '\n';
            break;
        case 4:
            std::cout << getVal(root, val) << '\n';
            break;
        case 5:
            std::cout << getPrev(root, val) << '\n';
            break;
        case 6:
            std::cout << getNext(root, val) << '\n';
            break;
        default:
            return -1; // RE
            break;
        }
    }
    std::cout << std::endl;
    return 0;
}
2021/8/17 21:16
加载中...