求使乙個二叉樹通過修改點權的方式成為二叉搜尋(排序)樹的最少修改次數。
二叉搜尋樹指對於任意節點 \(u\) 以及其左右兒子 \(v_1,v_2\),滿足 \(val(v_1)。
對平衡樹有一定了解的話,就知道平衡樹實際是在維護乙個中序遍歷不變的,深度接近 \(\log n\) 的二叉搜尋樹。
因此,本題要求的是,乙個數列 \(a\) (指這棵二叉樹的中序遍歷),修改成乙個單調上公升序列的最少次數。
顯然直接求 \(\operatorname\) 再進行一系列操作時錯誤的,例如 \(a=\\) 時,顯然不能只修改 \(5\)。抽象的講,就是對映成的 \(a\) 數列的每個區間不保證值域大於等於定義域。
設 \(f_i\) 表示前 \(i\) 位無需改變的數量,發現當且僅當 $ val_i-val_j\ge i-j$ 時,\(f_i\) 可以由 \(f_j\) 轉移。
把這個條件移項,就有 \(val_i-i\ge val_j-j\),於是處理出乙個陣列表示 \(val_i-i\),再求最長不降子串行即可。
這裡不能用樸素的求 \(\operatorname\),需要帶二分的 \(o(n\log n)\) 演算法(用 \(\operatorname\) 中自帶的查詢也可)。
int n,len;
int val[maxn],a[maxn],tot;
int tr[maxn][2];
inline void dfs(int u)
int f[maxn],g[maxn];
inline int get(int x)
else
}return res;
}int main()
for(int i=2;i<=n;i++)
dfs(1);
for(int i=1;i<=n;i++)
for(int i=1;i<=n;i++)
printf("%d\n",n-len);
return 0;
}
P3365 改造二叉樹
鏈結分析 求出中序遍歷後,然後使其變成上公升子串行。過程 每個點減去座標,然後nlogn求出最長不下降子串行,n ans即答案。做題時一直認為二叉樹就是完全二叉樹,然後一直mle。1 include2 include3 include4 include5 include6 include7 8usi...
洛谷 P3365 改造二叉樹
勤奮又善於思考的小l接觸了資訊學競賽,開始的學習十分順利。但是,小l對資料結構的掌握實在十分渣渣。所以,小l當時卡在了二叉樹。這一定難不倒聰明的你吧!如果你能幫小l解決這個問題,也許他會把最後的資產分給你1 16哦!輸入格式 第一行乙個正整數n表示二叉樹節點數。第二行n個正整數用空格分隔開,第i個數...
改造二叉樹
description 小y在學樹論時看到了有關二叉樹的介紹 在電腦科學中,二叉樹是每個結點最多有兩個子結點的有序樹。通常子結點被稱作 左孩子 和 右孩子 二叉樹被用作二叉搜尋樹和二叉堆。隨後他又和他人討論起了二叉搜尋樹。什麼是二叉搜尋樹呢?二叉搜尋樹首先是一棵二叉樹。設key p 表示結點p上的數...