NC22596 Rinne Loves Data Structure(STL)

题目链接

题意:
存 在 一 棵 空 树 存在一棵空树
每 次 向 根 插 入 一 个 值 , 如 果 该 值 小 于 当 前 点 , 往 左 插 入 , 否 则 往 右 每次向根插入一个值,如果该值小于当前点,往左插入,否则往右
如 果 左 右 存 在 值 , 再 次 进 行 判 断 , 直 到 空 插 入 如果左右存在值,再次进行判断,直到空插入
问 每 次 插 入 时 所 有 结 点 的 深 度 和 问每次插入时所有结点的深度和
题解:
n < = 3 e 5 , − 1 e 9 < = v a l < = 1 e 9 n<=3e5,-1e9<=val<=1e9 n<=3e5,1e9<=val<=1e9
观 察 可 得 , 每 次 插 入 的 点 , 一 定 是 和 已 插 入 点 和 该 值 相 差 最 小 的 相 连 观察可得,每次插入的点,一定是和已插入点和该值相差最小的相连
所 以 用 s e t 维 护 树 中 元 素 所以用set维护树中元素 set
每 次 插 入 时 进 行 查 找 他 的 相 邻 元 素 的 深 度 每次插入时进行查找他的相邻元素的深度
但 是 会 发 现 , 他 可 能 会 有 两 个 相 邻 元 素 但是会发现,他可能会有两个相邻元素
这 样 的 话 , 他 肯 定 会 去 较 深 的 元 素 连 接 这样的话,他肯定会去较深的元素连接
因 为 如 果 这 两 个 相 邻 元 素 都 在 树 中 , 他 们 一 定 有 一 条 链 连 接 因为如果这两个相邻元素都在树中,他们一定有一条链连接
这 个 元 素 如 果 放 在 上 面 的 点 , 那 么 一 定 会 多 出 一 条 子 树 这个元素如果放在上面的点,那么一定会多出一条子树
但 是 这 明 显 是 一 个 二 叉 搜 索 树 , 不 会 多 出 子 树 但是这明显是一个二叉搜索树,不会多出子树

然 后 由 于 他 可 能 没 有 后 继 或 者 前 驱 然后由于他可能没有后继或者前驱
我 们 可 以 找 到 两 个 哨 兵 放 在 两 边 我们可以找到两个哨兵放在两边
由 于 v a l 不 是 1 − n , 所 以 可 以 考 虑 一 下 离 散 , 这 样 哨 兵 为 0 和 n + 1 由于val不是1-n,所以可以考虑一下离散,这样哨兵为0和n+1 val1n0n+1
并 且 将 他 们 的 深 度 设 为 负 一 , 就 可 以 方 便 计 算 并且将他们的深度设为负一,就可以方便计算 便
这 样 一 来 每 次 相 加 当 前 深 度 即 可 这样一来每次相加当前深度即可

但 是 , n 不 是 那 么 大 , 不 怕 多 常 数 但是,n不是那么大,不怕多常数 n
所 以 干 脆 直 接 用 m a p 维 护 深 度 , 就 不 怕 v a l 的 大 小 没 法 存 在 数 组 里 了 所以干脆直接用map维护深度,就不怕val的大小没法存在数组里了 mapval
哨 兵 也 可 以 设 置 为 正 负 i n f 哨兵也可以设置为正负inf inf
AC代码

/*
    Author : zzugzx
    Lang : C++
    Blog : blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define endl '\n'
#define SZ(x) (int)x.size()
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int mod = 1e9 + 9;
const int MOD = 998244353;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int maxn = 1e6 + 10;
const int N = 1000;
const ll inf = 0x3f3f3f3f;
const int dir[][2]={{0, 1}, {1, 0}, {0, -1}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
//  freopen("in.txt", "r", stdin);
//  freopen("out.txt", "w", stdout);
    int n;
    cin >> n;
    set<int> s;
    map<int, int> d;
    s.insert(inf), s.insert(-inf);
    d[inf] = d[-inf] = -1;
    ll ans = 0;
    while (n--) {
        int x;
        cin >> x;
        auto p = s.lower_bound(x);
        d[x] = max(d[*prev(p)], d[*p]) + 1;
        s.insert(x);
        ans += d[x];
        cout << ans << endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值