这MLE,多是一件美逝啊~
查看原帖
这MLE,多是一件美逝啊~
297555
Zlc晨鑫楼主2022/1/17 10:54

orz各路神犇,萌新全M,裂开了。

样例过了,题解也用的是递归啊,为啥会M()

#include <queue>
#include <cstdio>
#include <utility>
#include <iostream>

using namespace std;

const int N = 1e4 + 10;

// l表示左儿子,v表示数值,s[i]表示i所在子树的节点个数
int l[N], r[N], v[N], c[N], s[N], idx = 0;

// x是要插入的数,k是节点编号
void add(const int x, int k)
{
    s[k]++;
    if (v[k] == x) c[k]++;
    else if (v[k] < x) // 右子树
    {
        if (r[k]) add(x, r[k]);
        else 
        {
            idx++;
            v[idx] = x;
            c[idx] = 1;
            s[idx] = 1;
            r[k] = idx;
        }
    }
    else 
    {
        if (l[k]) add(x, l[k]);
        else
        {
            idx++;
            v[idx] = x;
            c[idx] = 1;
            s[idx] = 1;
            l[k] = idx;
        }
    }
} 

// 通过值询问排名 
int ask_val(int x, int k)
{
    if (v[k] == x) return s[l[k]] + 1; // 不能返回s[k],因为那样会把右子树包括进去
    else if (x < v[k]) return ask_val(x, l[k]);
    else return s[l[k]] + 1 + ask_val(x, r[k]);
}

int ask_rank(int x, int t, int k)
{
    // printf("%d %d %d\n", x, t, k);
    if (x == t) return v[k];
    else if (x < t) return ask_rank(x, s[l[l[k]]] + 1, l[k]);
    else return ask_rank(x, t + s[l[r[k]]] + 1, r[k]);
    // s[l[k]] + 1 + s[l[r[k]]] + 1 是错的
}

int main()
{
    // 初始化根节点
    v[0] = 1e9 + 1;
    c[0] = s[0] = 0; // 因为根节点是虚拟节点,所以是0

    int m, n = 0;
    scanf("%d", &m);
    while (m--)
    {
        int op, x;
        scanf("%d %d", &op, &x);
        if (op == 1) printf("%d\n", ask_val(x, 1));
        else if (op == 2) printf("%d\n", ask_rank(x, n + 1, 0));
        else if (op == 3) printf("%d\n", ask_rank(ask_val(x, 1) - 1, n + 1, 0));
        else if (op == 4) printf("%d\n", ask_rank(ask_val(x, 1) + 1, n + 1, 0));
        else add(x, 0), n++;
        c[0] = s[0] = 0;
    }

    return 0;
}
2022/1/17 10:54
加载中...