題目:點此
chino樹是一棵具有某種性質的滿二叉樹,具體來說,對於這棵樹的每乙個非葉子節點,它的左子節點(a)(a)(a)的右子節點(c)(c)(c)與它的右子節點(b)(b)(b)的左子節點(d)(d)(d)的值相同,且ccc與ddd下方的子樹也完全相同。現在,chino想知道,要如何從根節點走到其中任意葉節點使路上經過的節點的權值之和最大。
先分析一下chino樹(滿二叉樹)的性質(節點編號)。
k層的滿二叉樹的最後乙個結點的編號是2k-1,第乙個葉子結點的編號是2k-1,由此可知,判斷節點是否為葉子:if(i>=pow(2,k-1)//i為結點編號 判斷此編號是否有對應節點:if(i>=0&&i<=pow(2,k)-1)//i為編號
定義乙個變數n_1儲存2k-1,再定義乙個變數x=n_1*2-1(就是2k-1)。
本題難點之一就是把以深搜序列輸入的樹變成在陣列裡儲存的樹(陣列儲存是廣搜序列),這個問題的解決方法是:在遞迴建樹的函式裡加乙個引數now_number,表示現在是陣列下標幾了,因為陣列下標是可以計算的:左子樹下標:now_number*2,右子樹下標:now_number*2+1。再加乙個max_node_number,表示最大的結點編號,判斷是否有左子樹或右子樹。
接下來就是判斷最大值了。使用先根遍歷遍歷二叉樹,由於這棵樹是用陣列儲存的,所以這篇部落格裡的in_oder函式的引數可以變為now_number,再加乙個now_weight,表示現在的結點權值和。
這個函式裡執行:先更新now_weight,把此節點權值加進去。然後判斷此節點是否為葉子,若是則判斷是否為最大值,若是則更新最大值,結束,不是葉子則按照先根遍歷的方法繼續遍歷。
最後主函式就是這些函式的結合。
(犯的錯誤和收穫全部丟失,無法敘述)
**:
1 #include 2 #include 3**using
namespace
std;
4int tree[17000000];5
intread()615
while(ch>='
0'&&ch<='9'
)16 s=s*10+ch-'
0',ch=getchar();
17return s*w;18}
1920
void maketree(int now_number,int
max_node_number)
27 maketree(now_number*2
,max_node_number);
28 maketree(now_number*2+1
,max_node_number);29}
30int pow(int
r)34
int data=1;35
if(r%2==1)38
int index=pow(r/2
);39
return index*index*data;40}
41int
maxx,n_1;
42void pre_oder(int now_weight,int
now_number)
48return;49
}50 pre_oder(now_weight,now_number*2
);51 pre_oder(now_weight,now_number*2+1
);52}53
intmain()
洛谷P2787 語文1(chin1) 理理思維
洛谷題目鏈結 珂朵莉樹吼啊!對於操作 1 直接普通查詢即可 對於操作 2 直接區間賦值即可 對於操作 3 其實也並不難,來一次計數排序後,依次插入即可,注意初始化計數器陣列 具體實現看 include include include include include defineset set ite...
洛谷P3372解題報告
題目描述如下 在這裡插入描述 由於是一道模板題就直接給注釋詳細的 include includeusing namespace std typedef long long ll long long int sum 0ll struct node tree 500005 void build ll l...
洛谷P1342 請柬解題報告
求去的路徑與回來的路徑和 1 n m 1000000 1 le n,m le 1000000 1 n,m 1000 000最短路 對於第一次碰到這種模型的oiers,這個地方可以講講的。顯然我們可以暴力跑n遍最短路。但是我們可以這麼想 我們出去是從乙個點到所有其他點,那麼我們能回來也從乙個點到所有其...