蒟蒻有個疑惑欸(指针版)
查看原帖
蒟蒻有個疑惑欸(指针版)
817044
cjwdyzxfblzs楼主2023/6/6 15:13

在查区间的时候,用一个fhq的类去把区间内所有的fhq都合并在一起,然后再查,这样的做法有没有正确性啊??? 蒟蒻写了好久,测试样例完全过不了。 求大佬调

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF32_MAX 2147483647
#define endl '\n'
void debug(string str)
{
    cout << "The " << str << " is OK." << endl;
}
mt19937 rnd(233);
inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - 48;
        ch = getchar();
    }
    return x * f;
}
const int N = 1e6;
struct node
{
    node *ls, *rs;
    int val, rand, size;
    explicit node(int x = 0) : size(1)
    {
        ls = rs = nullptr;
        rand = rnd();
        val = x;
        size = 1;
    }
};
class fhq_treap
{
public:
    node *root = new node();
    node *L = new node(), *R = new node();
    node *p = new node();
    void push_up(node *u)
    {
        u->size = (u->ls ? u->ls->size : 0) + (u->rs ? u->rs->size : 0) + 1;
    }
    void split(node *u, int x, node *&L, node *&R)
    {
        if (!u)
            return L = R = nullptr, void();
        int less = (u->ls ? u->ls->size : 0) + 1;
        if (x >= less)
        {
            L = u;
            split(u->rs, x - less, u->rs, R);
        }
        else
        {
            R = u;
            split(u->ls, x, L, u->ls);
        }
        push_up(u);
    }
    node *merge(node *L, node *R)
    {
        if (!L || !R)
            return L ? L : R;
        if (L->rand > R->rand)
        {
            L->rs = merge(L->rs, R);
            push_up(L);
            return L;
        }
        else
        {
            R->ls = merge(L, R->ls);
            push_up(R);
            return R;
        }
    }
    void split_val(node *u, int x, node *&L, node *&R)
    {
        if (!u)
            return L = R = nullptr, void();
        if (u->val <= x)
        {
            L = u;
            split_val(u->rs, x, u->rs, R);
        }
        else
        {
            R = u;
            split_val(u->ls, x, L, u->ls);
        }
        push_up(u);
    }
    int get_rank(int val)
    {
        split(root, val - 1, L, R);
        int rank = L->size + 1;
        root = merge(L, R);
        return rank;
    }
    int get_val(int rank)
    {
        node *p = root;
        while (p)
        {
            if ((p->ls ? p->ls->size : 0) + 1 == rank)
                break;
            else if ((p->ls ? p->ls->size : 0) >= rank && p->ls)
                p = p->ls;
            else
                rank -= (p->ls ? p->ls->size : 0) + 1,
                    p = p->rs;
        }
        return p->val;
    }
    void del(node *u)
    {
        if (!u)
            return;
        if (u->ls)
            del(u->ls);
        if (u->rs)
            del(u->rs);
        delete u;
    }
    int get_pre(int val)
    {
        split(root, val - 1, L, R);
        node *p = L;
        while (p->rs)
            p = p->rs;
        val = p->val;
        root = merge(L, R);
        return val;
    }
    int get_next(int val)
    {
        split(root, val, L, R);
        node *p = R;
        while (p->ls)
            p = p->ls;
        val = p->val;
        root = merge(L, R);
        return val;
    }
    void out(node *u)
    {
        if (u == nullptr)
            return;
        if (u->ls)
            out(u->ls);
        cout << u->val << endl;
        if (u->rs)
            out(u->rs);
    }
    ~fhq_treap()
    {
        delete root;
    }
};
struct code
{
    code *ls, *rs;
    fhq_treap fhq;
    int l, r;
    int val;
    explicit code()
    {
        ls = rs = nullptr;
        l = r = 0;
        val = 0;
    }
};
int a[N];
int n, m;
code *root = new code();
void push_up(code *u)
{
    if (u == nullptr)
        return;
    if (u->ls && u->rs)
        u->fhq.root = u->fhq.merge(u->ls->fhq.root, u->rs->fhq.root);
    else if (u->ls)
        u->fhq.root = u->ls->fhq.root;
    else
        u->fhq.root = u->rs->fhq.root;
}
void build(code *u, int l, int r)
{
    if (u == nullptr)
        return;
    u->l = l, u->r = r;
    if (l == r)
    {
        u->val = a[l];
        u->fhq.root = new node(u->val);
        return;
    }
    int mid = (l + r) >> 1;
    u->ls = new code();
    u->rs = new code();
    build(u->ls, l, mid);
    build(u->rs, mid + 1, r);
    push_up(u);
}
int get_rank(code *u, int l, int r, int val)
{
    if (u == nullptr)
        return 0;
    int ans = 0;
    if (l <= u->l && u->r <= r)
        return u->fhq.get_rank(val);
    int mid = (l + r) >> 1;
    if (l <= mid)
        ans += get_rank(u->ls, l, mid, val);
    if (r > mid)
        ans += get_rank(u->rs, mid + 1, r, val);
    return ans;
}
void gets_val(code *u, int l, int r, fhq_treap &vivo50)
{
    if (u == nullptr)
        return;
    if (l <= u->l && u->r <= r)
    {
        vivo50.root = vivo50.merge(vivo50.root, u->fhq.root);
        return;
    }
    int mid = (l + r) >> 1;
    if (l <= mid)
        gets_val(u->ls, l, mid, vivo50);
    if (r > mid)
        gets_val(u->rs, mid + 1, r, vivo50);
}
int get_val(int l, int r, int rank)
{
    fhq_treap fhq;
    gets_val(root, l, r, fhq);
    int res = fhq.get_val(rank);
    delete fhq.root;
    return res;
}
void modify(code *u, int pos, int val)
{
    if (u == nullptr)
        return;
    if (u->l == u->r && u->l == pos)
    {
        node *L, *R, *p;
        u->fhq.split(u->fhq.root, pos - 1, L, R);
        u->fhq.split(u->fhq.root, pos, R, p);
        u->fhq.root = u->fhq.merge(L, u->fhq.merge(new node(val), p));
        u->val = val;
        return;
    }
    int mid = (u->l + u->r) >> 1;
    if (mid >= pos)
        modify(u->ls, pos, val);
    else
        modify(u->rs, pos, val);
    push_up(u);
}
void get_all(code *u, int l, int r, fhq_treap &vivo)
{
    if (u == nullptr)
        return;
    if (l <= u->l and u->r <= r)
    {
        vivo.root = vivo.merge(vivo.root, u->fhq.root);
        return;
    }
    int mid = l + r >> 1;
    if (l <= mid)
        get_all(u->ls, l, mid, vivo);
    if (r > mid)
        get_all(u->rs, mid + 1, r, vivo);
}
int get_pre_next(int l, int r, int val, string str)
{
    fhq_treap fhq;
    get_all(root, l, r, fhq);
    if (str == "pre")
    {
        int pre = fhq.get_pre(val);
        return pre;
    }
    else
    {
        int ne = fhq.get_next(val);
        return ne;
    }
}
signed main()
{
    n = read();
    m = read();
    for (int i = 1; i <= n; i++)
        a[i] = read();
    build(root, 1, n);
    for (int i = 1; i <= m; i++)
    {
        int l, r, k, pos;
        int opt = read();
        if (opt == 1)
        {
            l = read(), r = read(), k = read();
            int rank = get_rank(root, l, r, k);
            cout << rank << endl;
        }
        else if (opt == 2)
        {
            l = read(), r = read(), k = read();
            int val =
            get_val(l, r, k);
            cout << val << endl;
        }
        else if (opt == 3)
        {
            pos = read(), k = read();
            modify(root, pos, k);
        }
        else if (opt == 4)
        {
            l = read(), r = read(), k = read();
            int pre = get_pre_next(l, r, k, "pre");
            cout << pre << endl;
        }
        else if (opt == 5)
        {
            l = read(), r = read(), k = read();
            int ne = get_pre_next(l, r, k, "next");
            cout << ne << endl;
        }
    }
    return 0;
}
2023/6/6 15:13
加载中...