[C艹] 估计时间复杂度O(qlogn),但全TLE求助大佬
查看原帖
[C艹] 估计时间复杂度O(qlogn),但全TLE求助大佬
557826
D_guard楼主2022/10/8 15:06

评测记录见此

蒟蒻代码如下:

#include <cstdio>
#include <iostream>
#define ll long long
#define m10(x) ((x << 3) + (x << 1))
// m10-位优化的*10,只用于快读...

using namespace std;
const ll INF = 2147483647;
const int MAXN = 1e4;
const int s = 1;
// s-根节点
int q, ope, x, tot, lm;
// tot-总值数(含重值);  lm-总节点数(不含重值)

struct tree
{
    int val, siz, num, fa, ls, rs;
} t[MAXN | 1];
/* 
    val-值;  siz-以该节点为根的树大小(含重值)
    num-该节点重值数;   fa-父节点
    ls、rs-左右子节点
*/

inline int qread()
{
    int ot = 0, tmp = getchar();
    while (tmp < 48 || tmp > 57)
        tmp = getchar();
    while (tmp >= 48 && tmp <= 57)
    {
        ot = m10(ot) + (tmp ^ 48);
        tmp = getchar();
    }
    return ot;
}
// 快读

inline int search(int x)
{
    int p = s;
    while (t[p].val != x)
        if (x < t[p].val)
            p = t[p].ls;
        else
            p = t[p].rs;
    return p;
}
// 查询值为x的节点编号

inline int find(int x)
{
    int p = s, ot = 1;
    while (t[p].val != x)
    {
        if (x < t[p].val)
            p = t[p].ls;
        else
        {
            ot += t[t[p].ls].siz + t[p].num;
            p = t[p].rs;
        }
    }
    ot += t[t[p].ls].siz;
    return ot;
}
//查询小于x的值个数

inline int ask(int x)
{
    int p = s;
    while (x < t[t[p].ls].siz + 1 || x > t[t[p].ls].siz + t[p].num)
    {
        if (x < t[t[p].ls].siz + 1)
            p = t[p].ls;
        else
        {
            x -= t[t[p].ls].siz + t[p].num;
            p = t[p].rs;
        }
    }
    return t[p].val;
}
// 查询第x小的值

inline ll lst(int x)
{
    int p = find(x);
    if (!(p ^ 1)) // 若x为第一个值
        return -1 * INF;
    int k = ask(p - 1);
    return k;
}
// 查询x的前驱

inline ll nxt(int x)
{
    int p = find(x);
    int tmp = search(x);
    if (p + t[tmp].num > tot)
        return INF;
    int k = ask(p + t[tmp].num);
    return k;
}
// 查询x的后驱

inline void ins(int x)
{
    int p = s;
    while (1)
    {
        ++t[p].siz; // x一定是p或其子节点的值
        if (t[p].val == x)
        {
            ++t[p].num;
            return;
        }
        if (x > t[p].val)
        {
            if (!t[p].rs)
            {
                t[++lm].val = x;
                t[lm].num = 1;
                t[lm].siz = 1;
                t[lm].fa = p;
                t[p].rs = lm;
                return;
            }
            p = t[p].rs;
        }
        else
        {
            if (!t[p].ls)
            {
                t[++lm].val = x;
                t[lm].num = 1;
                t[lm].siz = 1;
                t[lm].fa = p;
                t[p].ls = lm;
                return;
            }
            p = t[p].ls;
        }
    }
}
// 插入x

int main()
{
    q = qread();
    while (q--)
    {
        ope = qread();
        x = qread();
        switch (ope) // switch整整齐齐(
        {
        case 1:
            printf("%d\n", find(x));
            break;
        case 2:
            printf("%d\n", ask(x));
            break;
        case 3:
            printf("%lld\n", lst(x));
            break;
        case 4:
            printf("%lld\n", nxt(x));
            break;
        case 5:
            ++tot;
            if (!lm) // 若为插入的第一个值
            {
                t[++lm].val = x;
                t[lm].siz = 1;
                t[lm].num = 1;
            }
            else
                ins(x);
        }
    }
    return 0;
}

2022/10/8 15:06
加载中...