洛谷 P3365 改造二叉樹

2021-07-24 12:44:32 字數 1503 閱讀 1810

勤奮又善於思考的小l接觸了資訊學競賽,開始的學習十分順利。但是,小l對資料結構的掌握實在十分渣渣。

所以,小l當時卡在了二叉樹。

這一定難不倒聰明的你吧!如果你能幫小l解決這個問題,也許他會把最後的資產分給你1/16哦!

輸入格式:

第一行乙個正整數n表示二叉樹節點數。

第二行n個正整數用空格分隔開,第i個數ai表示結點i的原始數值。

此後n - 1行每行兩個非負整數fa, ch,第i + 2行描述結點i + 1的父親編號fa,以及父子關係ch,(ch = 0 表示i + 1為左兒子,ch = 1表示i + 1為右兒子)。

為了讓你稍微減輕些負擔,小l規定:結點1一定是二叉樹的根哦!

輸出格式:

僅一行包含乙個整數,表示最少的修改次數

輸入樣例#1:

3

2 2 2

1 01 1

輸出樣例#1:

2

20 % :n <= 10 , ai <= 100.

40 % :n <= 100 , ai <= 200

60 % :n <= 2000 .

100 % :n <= 10 ^ 5 ,  ai < 2 ^ 31. 

曾經的月賽題,說多皆淚啊。

由題意可知,跑一邊中序遍歷,再求乙個lis就好。

注意這裡跑lis演算法時,要用n*log(n)的,還有,把遍歷之後得到的陣列要這樣處理:

for(int i=1;i<=n;i++)

a[i]-=i;

計算之後的可用位置

舉個例子

1 2 3 3 4 5

↑你直接求lis的話

3和4之間沒有空位了,是錯解

但是每個位置-=i,代表這個要和前面的連上,中間得空一些位置

——by silvern

否則會坑20分。

#include#include#include#includeusing namespace std;

const int n=100005;

int n,m,w[n],f[n][2],a[n],dp[n];//0左兒子,1右兒子

void dfs(int u)//求中序遍歷

int main()

dfs(1);

for(int i=1;i<=n;i++)

a[i]-=i;

for(int i=1;i<=n;i++)

if(a[i]>=dp[m])

dp[++m]=a[i];

else

dp[lower_bound(dp+1,dp+m+1,a[i])-dp]=a[i];

printf("%d\n",n-m);

return 0;

}

P3365 改造二叉樹

鏈結分析 求出中序遍歷後,然後使其變成上公升子串行。過程 每個點減去座標,然後nlogn求出最長不下降子串行,n ans即答案。做題時一直認為二叉樹就是完全二叉樹,然後一直mle。1 include2 include3 include4 include5 include6 include7 8usi...

題解 P3365 改造二叉樹

求使乙個二叉樹通過修改點權的方式成為二叉搜尋 排序 樹的最少修改次數。二叉搜尋樹指對於任意節點 u 以及其左右兒子 v 1,v 2 滿足 val v 1 對平衡樹有一定了解的話,就知道平衡樹實際是在維護乙個中序遍歷不變的,深度接近 log n 的二叉搜尋樹。因此,本題要求的是,乙個數列 a 指這棵二...

洛谷 改造二叉樹(LIS)

勤奮又善於思考的小l接觸了資訊學競賽,開始的學習十分順利。但是,小l對資料結構的掌握實在十分渣渣。所以,小l當時卡在了二叉樹。這一定難不倒聰明的你吧!如果你能幫小l解決這個問題,也許他會把最後的資產分給你1 16哦!輸入格式 第一行乙個正整數n表示二叉樹節點數。第二行n個正整數用空格分隔開,第i個數...