题意:
告诉你有n个整数,按顺序构建一棵二叉查找树,既树中每一个节点满足左儿子小于节点,右儿子大于节点。求每次插入一个整数后树中每一个节点深度之和?

思路:
学过二叉查找树的都知道插入操作最坏情况为O(n^2)(链状时),所以模拟肯定过不了。
仔细观察二叉查找树,再分析下插入时进行的操作,我们可以发现对于一个节点,如果它是它父亲的左儿子,则它父亲是整棵树中大于它的最小的节点,如果它是它父亲的右儿子则它父亲是整棵树中小于它的最大的节点,所以你插入一个节点后,它的父节点要么不存在,要么就是小于他的最大节点或大于它的最小节点,那究竟是选哪个做父亲呢,由于在你没插入之前,他们是相邻的,所以他们相连,而你的大小在他们之间,所以你不可能是其中一个的兄弟节点,因此你只能是认最大深度的那个相邻节点为父亲。
发现了这些,你就可以用set容器二分查找相邻节点,用map容器将节点与深度联系。

代码:

#include <bits/stdc++.h>

#define inf 1000000007
#define eps 0.00000001
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int maxn=100005;

inline int read()
{
    char c=getchar();
    int f=1, x=0;
    while(c>'9'||c<'0')
    {
        if(c=='-')
        {
            f=-1;
        }
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=(x<<3)+(x<<1)+(c^48);
        c=getchar();
    }
    return f*x;
}

map<int,int> ma;
set<int> se;
set<int>::iterator it;

int main()
{
    int n;
    scanf("%d",&n);
    ll ans=0;
    for(int i=0;i<n;i++)
    {
        int x;
        scanf("%d",&x);
        se.insert(x);
        it=se.find(x);
        it++;
        int p1=-1, p2=-1;
        if(it!=se.end())
        {
            p1=ma[*it];
        }
        it--;
        if(it!=se.begin())
        {
            it--;
            p2=ma[*it];
        }
        ma[x]=max(p1,p2)+1;
        ans=ans+ma[x];
        printf("%lld\n",ans);
    }
    return 0;
}