題解 P3365 改造二叉樹

2022-09-20 11:36:12 字數 1010 閱讀 1030

求使乙個二叉樹通過修改點權的方式成為二叉搜尋(排序)樹的最少修改次數。

二叉搜尋樹指對於任意節點 \(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上的數...