P3369 Fhq无头绪全挂,一半M,一半T, 求教
查看原帖
P3369 Fhq无头绪全挂,一半M,一半T, 求教
368934
Diang楼主2022/2/23 17:51
#include<bits/stdc++.h>

using namespace std;
typedef long long dat;
const int N = 2e5;

int n, m;

class fhq{
public:
    #define lc(x) h[x].ls
    #define rc(x) h[x].rs
    struct nod{
        int ls, rs, rd, siz;
        dat val;
    }h[N << 2];

    int rt, tot;
    typedef pair<int, int> pii;
    fhq():rt(), tot() {}

    void pushup(int x)
    { h[x].siz = h[lc(x)].siz + h[rc(x)].siz + 1; }

    int merge(int x, int y)
    {
        if(!x||!y) return x | y;
        if(h[x].rd > h[y].rd) {
            rc(x) = merge(rc(x), y);
            pushup(x); return x;
        }
        else {
            lc(y) = merge(x, lc(y));
            pushup(y); return y;
        }
    }
    int merge(pii a) { return merge(a.first, a.second); }
    pii split(int x, int k)
    {
        if(!x) return make_pair(0, 0);
        pii ans;
        if(h[lc(x)].siz >= k) {
            ans = split(lc(x), k);
            lc(x) = ans.second; pushup(x); ans.second = x;
            return ans;
        }
        else{
            ans = split(rc(x), k - h[lc(x)].siz - 1);
            rc(x) = ans.first; pushup(x); ans.first = x;
            return ans;
        }
    }

    int newNod(int v)
    {
        h[++tot].val = v;
        h[tot].rd = rand();
        h[tot].siz = 1;
        return tot;
    }

    int rank(int v)
    {
        int c = 0;
        int p = rt;
        while(p) {
            if(h[p].val >= v) p = lc(p);
            else c += h[lc(p)].siz + 1, p = rc(p);
        }
        return c + 1;
    }

    int val(int k)
    {
        pii k1 = split(rt, k - 1);
        pii k2 = split(k1.second, 1);
        int c = h[k2.first].val;
        rt = merge(k1.first, merge(k2));
        return c;
    }

    void insert(int x)
    {
        int k = rank(x);
        pii k1 = split(rt, k - 2);
        pii k2 = split(rt, 1);
        rt = merge(k1.first, merge(merge(k2.first, newNod(x)), k2.second));
    }

    void dlt(int x)
    {
        int k = rank(x);
        pii k1 = split(rt, k - 1);
        pii k2 = split(rt, 1);
        rt = merge(k1.first, k2.second);
    }

    int pre(int x) {
        return val(rank(x) - 1);
    }
    int nex(int x) {
        return val(rank(x) + 1);
    }

}T;

int main()
{
    scanf("%d", &n);
    int opt, x;
    while(n--)
    {
        scanf("%d%d", &opt, &x);
        switch(opt)
        {
        case 1:
            T.insert(x);
            break;
        case 2:
            T.dlt(x);
            break;
        case 3:
            printf("%d\n", T.rank(x));
            break;
        case 4:
            printf("%d\n", T.val(x));
                break;
        case 5:
            printf("%d\n", T.pre(x));
                break;
        case 6:
            printf("%d\n", T.nex(x));
                break;
        }
    }
    return 0;
}
```cpp
2022/2/23 17:51
加载中...