#题目
树
http://www.gdfzoj.com/oj/contest/248/problems/1
#分析
- 哇,这个题虽然是放在 提高 B 组 第一题,可是却一脸懵逼。
- 结束后听 ZW 半分钟讲了这题,恍然大悟……
- 这是样例画出的查找树(水平方向按数值排好顺序)
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xlsJwfKO-1659756919614)(https://img-blog.csdn.net/20171107185828538)]
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pOU0sudO-1659756919615)(https://img-blog.csdn.net/20171107190751433)]
- 自己模拟一下,会发现,新加入一个数后,找到它(以水平向坐标为标准)左右两个点,那么它的深度就是左右深度较大值的下一层。
- 用个 set 记录节点信息(数值和深度),每次找左右两个节点,操作一下即可,刚好练一练 STL。
- 关于边界的细节可以看看程序。
#程序
#include <cstdio>
#include <algorithm>
#include <set>
using namespace std;
typedef pair<int,int> pr;
int n,x,k;
long long ans;
set <pr> S;
set <pr>::iterator it;
pr l,r;
int main(){
scanf("%d",&n);
while (scanf("%d",&x)!=EOF){
it=S.lower_bound((pr){x,0});
if (it!=S.end()) r=*it;
else r=(pr){-1,-1};
if (it==S.begin()) l=(pr){-1,-1};
else {it--; l=*it;}
k=max(l.second,r.second)+1;
S.insert((pr){x,k});
printf("%lld\n",ans+=k);
}
}
#提示
- 这题值得积累……