description:
对于一颗二叉树每次进行insert操作 ,输出当前节点的深度和
solution:
如果维护普通的BST的话有可能因为树退化成链导致TLE,防止树退化成链可以大力套平衡树上去是可以ac的.但这题可以不用这么麻烦,通过观察,我们可以知道插入结点时会有四种情况
1.有pre和suc
2.有pre无suc
3.无pre有suc
4.两个都没
维护一个dep数组 来代表结点深度
维护set代表树的情况 通过二分来找当前点为以上四种情况哪一种 对应分别处理。
code:
#include <bits/stdc++.h> using namespace std; #define LL long long #define ULL unsigned long long #define mes(x, a) memset(x, a, sizeof(x)); #define sca(a) scanf("%d", &a) #define lowbit(x) x&(-x) #define mk make_pair #define pb(x) push_back(x) #define all(x) (x).begin(), (x).end() #define fi first #define se second #define lson v << 1 #define rson v << 1 | 1 #define pii pair<int, int> inline void read(int &x) { x=0; int flag_read=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-') flag_read=-1; c=getchar(); } while(c>='0'&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); } x *= flag_read; } void out(int x){ if(x > 9){ out(x / 10); } putchar(x % 10 + '0'); } const int N = 3e5 + 50; set <int> s; int dep[N],n; int main(){ ios::sync_with_stdio(0); int n;cin >> n; LL res = 0; while(n --){ int x;cin >> x; if(s.size() == 0){// 没有结点 cout << 0 << '\n'; s.insert(x); continue; } auto it = s.lower_bound(x); if(*it == x){ cout << res << '\n'; continue; } if(it == s.begin()){// pre dep[x] = dep[*it] + 1; res += dep[x]; } else if(it == s.end()){// suc -- it; dep[x] = dep[*it] + 1; res += dep[x]; } else{// pre & suc dep[x] = dep[*it] + 1; -- it; dep[x] = max(dep[x],dep[*it] + 1); res += dep[x]; } s.insert(x); cout << res << '\n'; } return 0; }