题意:
存
在
一
棵
空
树
存在一棵空树
存在一棵空树
每
次
向
根
插
入
一
个
值
,
如
果
该
值
小
于
当
前
点
,
往
左
插
入
,
否
则
往
右
每次向根插入一个值,如果该值小于当前点,往左插入,否则往右
每次向根插入一个值,如果该值小于当前点,往左插入,否则往右
如
果
左
右
存
在
值
,
再
次
进
行
判
断
,
直
到
空
插
入
如果左右存在值,再次进行判断,直到空插入
如果左右存在值,再次进行判断,直到空插入
问
每
次
插
入
时
所
有
结
点
的
深
度
和
问每次插入时所有结点的深度和
问每次插入时所有结点的深度和
题解:
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
由于val不是1−n,所以可以考虑一下离散,这样哨兵为0和n+1
并
且
将
他
们
的
深
度
设
为
负
一
,
就
可
以
方
便
计
算
并且将他们的深度设为负一,就可以方便计算
并且将他们的深度设为负一,就可以方便计算
这
样
一
来
每
次
相
加
当
前
深
度
即
可
这样一来每次相加当前深度即可
这样一来每次相加当前深度即可
但
是
,
n
不
是
那
么
大
,
不
怕
多
常
数
但是,n不是那么大,不怕多常数
但是,n不是那么大,不怕多常数
所
以
干
脆
直
接
用
m
a
p
维
护
深
度
,
就
不
怕
v
a
l
的
大
小
没
法
存
在
数
组
里
了
所以干脆直接用map维护深度,就不怕val的大小没法存在数组里了
所以干脆直接用map维护深度,就不怕val的大小没法存在数组里了
哨
兵
也
可
以
设
置
为
正
负
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;
}