WA #6#10,线段树套splay求助
查看原帖
WA #6#10,线段树套splay求助
225253
EаrringYYR楼主2020/6/12 21:51

#6在6000+行错误,#10在13000+行错误

#include <bits/stdc++.h>
using namespace std;
inline int read()
{
    int cnt = 0, f = 1;
    char c = getchar();
    while (!isdigit(c))
    {
        if (c == '-')
            f = -f;
        c = getchar();
    }
    while (isdigit(c))
    {
        cnt = (cnt << 3) + (cnt << 1) + (c ^ 48);
        c = getchar();
    }
    return cnt * f;
}
const int INF = 2147483647;
const int N = 60 * (int)1e5 + 10;
int a[N], rt[N << 2], ans, n, m, opr, l, r, k;
struct BST
{
    int ch[N][2], val[N], fa[N], cnt[N], siz[N];
    int tot;
#define ls(x) ch[x][0]
#define rs(x) ch[x][1]
    void Init()
    {
        memset(ch, 0, sizeof(ch));
        memset(val, 0, sizeof(val));
        memset(fa, 0, sizeof(fa));
        memset(cnt, 0, sizeof(cnt));
        memset(siz, 0, sizeof(siz));
    }
    void update(int p)
    {
        siz[p] = siz[ls(p)] + siz[rs(p)] + cnt[p];
    }
    void rotate(int x)
    {
        int y = fa[x], z = fa[y];
        int k = (x == rs(y));
        ch[z][y == rs(z)] = x;
        fa[x] = z;
        ch[y][k] = ch[x][k ^ 1];
        fa[ch[x][k ^ 1]] = y;
        ch[x][k ^ 1] = y;
        fa[y] = x;
        update(y), update(x);
    }
    void splay(int x, int goal, int &root)
    {
        while (fa[x] != goal)
        {
            int y = fa[x], z = fa[y];
            if (z != goal)
                (ls(z) == y) ^ (ls(y) == x) ? rotate(x) : rotate(y);
            rotate(x);
        }
        if (!goal)
            root = x;
    }
    void insert(int x, int &root)
    {
        if (!root)
        {
            root = ++tot;
            siz[root] = cnt[root] = 1;
            val[root] = x;
            return;
        }
        int p = root, Fa = 0;
        while (p && val[p] != x)
            siz[p]++, Fa = p, p = ch[p][x > val[p]];
        if (p)
            ++cnt[p];
        else
        {
            p = ++tot;
            if (Fa)
                ch[Fa][x > val[Fa]] = p;
            fa[p] = Fa, siz[p] = cnt[p] = 1, val[p] = x;
        }
        splay(p, 0, root);
    }
    int pre(int x, int &root)
    {
        int p = root, res = -2147483647;
        while (p)
        {
            if (val[p] > res && val[p] < x)
                res = val[p];
            p = ch[p][val[p] < x];
        }
        return res;
    }
    int suc(int x, int &root)
    {
        int p = root, res = 2147483647;
        while (p)
        {
            if (val[p] < res && val[p] > x)
                res = val[p];
            p = ch[p][val[p] < x];
        }
        return res;
    }
    int find(int x, int root)
    {
        int p = root;
        while (p && val[p] != x)
            p = ch[p][val[p] < x];
        return p;
    }
    int rk(int x, int &root)
    {
        int p = root, ans = 0;
        while (p)
        {
            if (x < val[p])
                p = ls(p);
            else
            {
                ans += siz[ls(p)];
                if (val[p] == x)
                    return splay(p, 0, root), ans;
                ans += cnt[p];
                p = rs(p);
            }
        }
        return ans;
    }
    void Delete(int x, int &root)
    {
        int pos = find(x, root);
        if (!pos)
            return;
        if (cnt[pos] > 1)
        {
            --siz[pos];
            --cnt[pos];
            return;
        }
        splay(pos, 0, root);
        if (!ls(pos))
        {
            root = rs(pos);
            fa[root] = 0;
            return;
        }
        int lef = ls(pos), rig = rs(pos);
        while (rs(lef))
            lef = rs(lef);
        splay(lef, 0, root);
        fa[rig] = lef, rs(lef) = rig;
        update(lef);
    }
} Splay;
struct segmentTree
{
    int l[N << 2], r[N << 2];
    void build(int p, int L, int R)
    {
        l[p] = L, r[p] = R;
        for (register int i = L; i <= R; ++i)
            Splay.insert(a[i], rt[p]);
        if (L == R)
            return;
        int mid = (L + R) >> 1;
        build(p << 1, L, mid);
        build(p << 1 | 1, mid + 1, R);
    }
    int Rank(int p, int L, int R, int val)
    {
        int ans = 0;
        if (L <= l[p] && R >= r[p])
            return Splay.rk(val, rt[p]);
        int mid = (l[p] + r[p]) >> 1;
        if (L <= mid)
            ans += Rank(p << 1, L, R, val);
        if (R > mid)
            ans += Rank(p << 1 | 1, L, R, val);
        return ans;
    }
    int kth(int L, int R, int val)
    {
        int l = 0, r = (int)1e8;
        while (l < r)
        {
            int mid = (l + r + 1) >> 1;
            if (Rank(1, L, R, mid) + 1 <= val)
                l = mid;
            else
                r = mid - 1;
        }
        return l;
    }
    void modify(int p, int x, int pos, int cur)
    {
        Splay.Delete(x, rt[p]);
        Splay.insert(cur, rt[p]);
        if (l[p] == r[p])
        {
            a[pos] = cur;
            return;
        }
        int mid = (l[p] + r[p]) >> 1;
        if (pos <= mid)
            modify(p << 1, x, pos, cur);
        else
            modify(p << 1 | 1, x, pos, cur);
    }
    int Pre(int p, int L, int R, int x)
    {
        if (L <= l[p] && R >= r[p])
            return Splay.pre(x, rt[p]);
        int ans = -INF;
        int mid = (l[p] + r[p]) >> 1;
        if (L <= mid)
            ans = max(ans, Pre(p << 1, L, R, x));
        if (R > mid)
            ans = max(ans, Pre(p << 1 | 1, L, R, x));
        return ans;
    }
    int Suc(int p, int L, int R, int x)
    {
        if (L <= l[p] && R >= r[p])
            return Splay.suc(x, rt[p]);
        int ans = INF;
        int mid = (l[p] + r[p]) >> 1;
        if (L <= mid)
            ans = min(ans, Suc(p << 1, L, R, x));
        if (R > mid)
            ans = min(ans, Suc(p << 1 | 1, L, R, x));
        return ans;
    }
} segT;
int main()
{
    n = read(), m = read();
    Splay.Init();
    for (register int i = 1; i <= n; ++i)
        a[i] = read();
    segT.build(1, 1, n);
    for (register int i = 1; i <= m; ++i)
    {
        opr = read();
        if (opr == 1)
        {
            l = read(), r = read(), k = read();
            printf("%d\n", segT.Rank(1, l, r, k) + 1);
        }
        if (opr == 2)
        {
            l = read(), r = read(), k = read();
            printf("%d\n", segT.kth(l, r, k));
        }
        if (opr == 3)
        {
            l = read(), k = read();
            segT.modify(1, a[l], l, k), a[l] = k;
        }
        if (opr == 4)
        {
            l = read(), r = read(), k = read();
            printf("%d\n", segT.Pre(1, l, r, k));
        }
        if (opr == 5)
        {
            l = read(), r = read(), k = read();
            printf("%d\n", segT.Suc(1, l, r, k));
        }
    }
    return 0;
}
2020/6/12 21:51
加载中...